lora-python 0.19.0__tar.gz → 0.20.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.
Files changed (394) hide show
  1. {lora_python-0.19.0 → lora_python-0.20.0}/Cargo.lock +19 -19
  2. {lora_python-0.19.0 → lora_python-0.20.0}/Cargo.toml +13 -13
  3. {lora_python-0.19.0 → lora_python-0.20.0}/PKG-INFO +1 -1
  4. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-binding-buffer/src/stream.rs +143 -43
  5. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/src/stream.rs +4 -3
  6. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/tests/test_sync.py +44 -0
  7. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-compiler/src/lib.rs +1 -1
  8. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-compiler/src/logical.rs +11 -0
  9. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-compiler/src/optimizer.rs +25 -4
  10. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-compiler/src/physical.rs +3 -0
  11. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-compiler/src/plan_tree.rs +7 -0
  12. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-compiler/src/planner.rs +2 -0
  13. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/index_acceleration.rs +44 -0
  14. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/stream.rs +3 -1
  15. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/stream.rs +62 -15
  16. lora_python-0.20.0/crates/lora-database/tests/bbox_antimeridian.rs +72 -0
  17. lora_python-0.20.0/crates/lora-database/tests/fulltext_list_properties.rs +39 -0
  18. lora_python-0.20.0/crates/lora-database/tests/limit_skip_counts.rs +78 -0
  19. lora_python-0.20.0/crates/lora-database/tests/pattern_subquery_property_seek.rs +66 -0
  20. lora_python-0.20.0/crates/lora-database/tests/shared_index_value_writes.rs +114 -0
  21. lora_python-0.20.0/crates/lora-database/tests/sort_limit_probe.rs +120 -0
  22. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/transactions.rs +114 -0
  23. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/geo.rs +6 -8
  24. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/expr.rs +22 -3
  25. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/executor/helpers.rs +90 -33
  26. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/executor/immutable.rs +4 -3
  27. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/executor/mod.rs +2 -2
  28. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/executor/mutable.rs +4 -3
  29. lora_python-0.20.0/crates/lora-executor/src/executor/sort.rs +412 -0
  30. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/sort.rs +13 -8
  31. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/traits.rs +12 -12
  32. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/lib.rs +12 -12
  33. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/fulltext_index.rs +19 -2
  34. lora_python-0.20.0/crates/lora-store/src/memory/id_set.rs +542 -0
  35. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/mod.rs +5 -4
  36. lora_python-0.20.0/crates/lora-store/src/types/spatial/bbox.rs +37 -0
  37. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/spatial/mod.rs +2 -0
  38. {lora_python-0.19.0 → lora_python-0.20.0}/pyproject.toml +1 -1
  39. {lora_python-0.19.0 → lora_python-0.20.0}/python/lora_python/_async.py +3 -1
  40. lora_python-0.19.0/crates/lora-executor/src/executor/sort.rs +0 -89
  41. lora_python-0.19.0/crates/lora-store/src/memory/id_set.rs +0 -260
  42. {lora_python-0.19.0 → lora_python-0.20.0}/LICENSE +0 -0
  43. {lora_python-0.19.0 → lora_python-0.20.0}/README.md +0 -0
  44. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-binding-buffer/Cargo.toml +0 -0
  45. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-binding-buffer/src/lib.rs +0 -0
  46. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/.gitignore +0 -0
  47. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/Cargo.toml +0 -0
  48. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/LICENSE +0 -0
  49. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/README.md +0 -0
  50. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/build.rs +0 -0
  51. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/examples/async_demo.py +0 -0
  52. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/examples/basic.py +0 -0
  53. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/src/errors.rs +0 -0
  54. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/src/from_python.rs +0 -0
  55. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/src/gil.rs +0 -0
  56. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/src/lib.rs +0 -0
  57. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/src/to_python.rs +0 -0
  58. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/tests/test_async.py +0 -0
  59. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/tests/test_concurrency.py +0 -0
  60. {lora_python-0.19.0 → lora_python-0.20.0}/crates/bindings/lora-python/tests/test_explain_profile.py +0 -0
  61. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/Cargo.toml +0 -0
  62. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/analyzer/builtin_signatures.rs +0 -0
  63. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/analyzer/clauses.rs +0 -0
  64. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/analyzer/expressions.rs +0 -0
  65. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/analyzer/mod.rs +0 -0
  66. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/analyzer/patterns.rs +0 -0
  67. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/analyzer/state.rs +0 -0
  68. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/analyzer/tests.rs +0 -0
  69. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/errors.rs +0 -0
  70. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/lib.rs +0 -0
  71. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/resolved.rs +0 -0
  72. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/scope.rs +0 -0
  73. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/src/symbols.rs +0 -0
  74. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-analyzer/tests/error_messages.rs +0 -0
  75. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-ast/Cargo.toml +0 -0
  76. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-ast/src/ast.rs +0 -0
  77. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-ast/src/lib.rs +0 -0
  78. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-builtins-meta/Cargo.toml +0 -0
  79. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-builtins-meta/src/lib.rs +0 -0
  80. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-compiler/Cargo.toml +0 -0
  81. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-compiler/src/pattern.rs +0 -0
  82. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/Cargo.toml +0 -0
  83. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/README.md +0 -0
  84. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/advanced.rs +0 -0
  85. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/concurrency_guard.rs +0 -0
  86. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/concurrent.rs +0 -0
  87. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/engine.rs +0 -0
  88. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/fixtures.rs +0 -0
  89. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/memory.rs +0 -0
  90. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/memory_baseline.json +0 -0
  91. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/perf_smoke.rs +0 -0
  92. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/perf_smoke_baseline.json +0 -0
  93. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/query_implementations.rs +0 -0
  94. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/realistic.rs +0 -0
  95. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/scale.rs +0 -0
  96. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/temporal_spatial.rs +0 -0
  97. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/benches/wal.rs +0 -0
  98. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/examples/bulk_probe.rs +0 -0
  99. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/examples/heap_probe.rs +0 -0
  100. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/examples/keyset_probe.rs +0 -0
  101. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/examples/optional_probe.rs +0 -0
  102. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/examples/perf_probe.rs +0 -0
  103. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/examples/pushdown_probe.rs +0 -0
  104. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/changes/build.rs +0 -0
  105. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/changes/history.rs +0 -0
  106. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/changes/mod.rs +0 -0
  107. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/builder.rs +0 -0
  108. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/changes.rs +0 -0
  109. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/compile.rs +0 -0
  110. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/execute.rs +0 -0
  111. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/explain.rs +0 -0
  112. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/graph_api.rs +0 -0
  113. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/mod.rs +0 -0
  114. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/occ.rs +0 -0
  115. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/procedures.rs +0 -0
  116. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/profile.rs +0 -0
  117. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/pull_mode.rs +0 -0
  118. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/replay.rs +0 -0
  119. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/row_projection.rs +0 -0
  120. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/schema.rs +0 -0
  121. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/show_pipeline.rs +0 -0
  122. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/database/write_guard.rs +0 -0
  123. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/durable_io.rs +0 -0
  124. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/error.rs +0 -0
  125. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/explain.rs +0 -0
  126. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/io.rs +0 -0
  127. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/lib.rs +0 -0
  128. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/live_store.rs +0 -0
  129. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/named.rs +0 -0
  130. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/plan_cache.rs +0 -0
  131. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/snapshot/json.rs +0 -0
  132. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/snapshot/mod.rs +0 -0
  133. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/snapshot/store.rs +0 -0
  134. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/transaction.rs +0 -0
  135. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/wal/admin.rs +0 -0
  136. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/wal/archive/format.rs +0 -0
  137. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/wal/archive/lock.rs +0 -0
  138. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/wal/archive/platform.rs +0 -0
  139. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/wal/archive/worker.rs +0 -0
  140. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/wal/archive/workspace.rs +0 -0
  141. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/wal/archive.rs +0 -0
  142. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/wal/mod.rs +0 -0
  143. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/src/wal/write_scope.rs +0 -0
  144. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/advanced_queries.rs +0 -0
  145. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/aggregation.rs +0 -0
  146. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/and_or_short_circuit.rs +0 -0
  147. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/backend_stub.rs +0 -0
  148. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/binary.rs +0 -0
  149. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/borrowed_variable_reads.rs +0 -0
  150. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/builtin_namespaces.rs +0 -0
  151. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/call_subquery_writes.rs +0 -0
  152. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/change_feed.rs +0 -0
  153. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/comparison_ordering.rs +0 -0
  154. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/constraints.rs +0 -0
  155. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/create.rs +0 -0
  156. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/cypher_compat.rs +0 -0
  157. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/docs_examples.rs +0 -0
  158. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/early_limit.rs +0 -0
  159. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/empty_ranges.rs +0 -0
  160. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/error_messages.rs +0 -0
  161. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/errors.rs +0 -0
  162. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/explain_estimates.rs +0 -0
  163. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/explain_profile.rs +0 -0
  164. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/expressions.rs +0 -0
  165. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/foreach.rs +0 -0
  166. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/fulltext_index.rs +0 -0
  167. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/functions_extended.rs +0 -0
  168. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/index_acceleration.rs +0 -0
  169. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/invariants.rs +0 -0
  170. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/managed_snapshots.rs +0 -0
  171. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/match.rs +0 -0
  172. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/merge.rs +0 -0
  173. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/merge_bound_end.rs +0 -0
  174. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/null_properties_and_deferred_existence.rs +0 -0
  175. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/optional_match_correlated.rs +0 -0
  176. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/order_by_index.rs +0 -0
  177. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/order_limit_semantics.rs +0 -0
  178. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/ordering.rs +0 -0
  179. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/parameters.rs +0 -0
  180. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/parser.rs +0 -0
  181. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/paths.rs +0 -0
  182. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/pattern_subquery_rel_properties.rs +0 -0
  183. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/pattern_subquery_scope.rs +0 -0
  184. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/pattern_subquery_var_length.rs +0 -0
  185. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/planner_pushdown.rs +0 -0
  186. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/procedure_yield.rs +0 -0
  187. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/projection.rs +0 -0
  188. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/range_scan_other_kinds.rs +0 -0
  189. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/scale.rs +0 -0
  190. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/schema.rs +0 -0
  191. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/schema_in_transaction.rs +0 -0
  192. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/seeds.rs +0 -0
  193. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/snapshot.rs +0 -0
  194. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/spatial.rs +0 -0
  195. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/temporal.rs +0 -0
  196. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/temporal_constructor_functions.rs +0 -0
  197. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/temporal_constructors.rs +0 -0
  198. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/temporal_map_components.rs +0 -0
  199. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/temporal_range_index.rs +0 -0
  200. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/temporal_strings.rs +0 -0
  201. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/temporal_time_zones.rs +0 -0
  202. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/temporal_zone_accessors.rs +0 -0
  203. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/test_helpers.rs +0 -0
  204. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/timeouts.rs +0 -0
  205. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/types_advanced.rs +0 -0
  206. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/union.rs +0 -0
  207. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/unknown_names.rs +0 -0
  208. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/unwind_ingestion.rs +0 -0
  209. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/update.rs +0 -0
  210. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/var_length_bound_endpoint.rs +0 -0
  211. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/var_length_hop_ranges.rs +0 -0
  212. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/vector_index.rs +0 -0
  213. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/vectors.rs +0 -0
  214. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/wal.rs +0 -0
  215. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/where_clause.rs +0 -0
  216. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/with.rs +0 -0
  217. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/with_predicates.rs +0 -0
  218. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/write_results.rs +0 -0
  219. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-database/tests/write_scaling.rs +0 -0
  220. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/Cargo.toml +0 -0
  221. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/cancel.rs +0 -0
  222. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/errors.rs +0 -0
  223. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/binops.rs +0 -0
  224. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/bits_ns.rs +0 -0
  225. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/bytes_ns.rs +0 -0
  226. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/cast_ns.rs +0 -0
  227. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/crypto.rs +0 -0
  228. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/edge.rs +0 -0
  229. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/index_ns.rs +0 -0
  230. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/json_ns.rs +0 -0
  231. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/list.rs +0 -0
  232. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/map_ns.rs +0 -0
  233. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/math_ns.rs +0 -0
  234. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/mod.rs +0 -0
  235. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/node.rs +0 -0
  236. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/number.rs +0 -0
  237. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/path.rs +0 -0
  238. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/string_ns.rs +0 -0
  239. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/temporal.rs +0 -0
  240. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/temporal_build.rs +0 -0
  241. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/text.rs +0 -0
  242. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/type_ns.rs +0 -0
  243. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/uuid_ns.rs +0 -0
  244. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/value.rs +0 -0
  245. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/builtins/vector_ns.rs +0 -0
  246. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/errors.rs +0 -0
  247. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/functions.rs +0 -0
  248. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/mod.rs +0 -0
  249. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/point.rs +0 -0
  250. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/regex.rs +0 -0
  251. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/eval/vector.rs +0 -0
  252. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/executor/aggregation.rs +0 -0
  253. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/executor/optional.rs +0 -0
  254. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/lib.rs +0 -0
  255. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/profile.rs +0 -0
  256. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/aggregate.rs +0 -0
  257. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/call_subquery.rs +0 -0
  258. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/columns.rs +0 -0
  259. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/context.rs +0 -0
  260. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/expand.rs +0 -0
  261. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/filter.rs +0 -0
  262. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/hydration.rs +0 -0
  263. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/mod.rs +0 -0
  264. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/mutable.rs +0 -0
  265. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/optional.rs +0 -0
  266. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/path.rs +0 -0
  267. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/projection.rs +0 -0
  268. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/scan.rs +0 -0
  269. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/shape.rs +0 -0
  270. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/source.rs +0 -0
  271. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/tests.rs +0 -0
  272. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/pull/union.rs +0 -0
  273. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/src/value.rs +0 -0
  274. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-executor/tests/error_messages.rs +0 -0
  275. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-io/Cargo.toml +0 -0
  276. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-io/src/csv.rs +0 -0
  277. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-io/src/format.rs +0 -0
  278. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-io/src/json_array.rs +0 -0
  279. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-io/src/jsonl.rs +0 -0
  280. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-io/src/lib.rs +0 -0
  281. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-io/src/mapping.rs +0 -0
  282. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-io/src/value_json.rs +0 -0
  283. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/Cargo.toml +0 -0
  284. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/cypher.pest +0 -0
  285. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/errors.rs +0 -0
  286. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/lib.rs +0 -0
  287. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/parser/clauses.rs +0 -0
  288. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/parser/expressions.rs +0 -0
  289. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/parser/literals.rs +0 -0
  290. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/parser/mod.rs +0 -0
  291. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/parser/patterns.rs +0 -0
  292. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/parser/query.rs +0 -0
  293. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/parser/schema.rs +0 -0
  294. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/parser/tests.rs +0 -0
  295. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/src/parser/util.rs +0 -0
  296. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-parser/tests/error_messages.rs +0 -0
  297. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/Cargo.toml +0 -0
  298. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/body.rs +0 -0
  299. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/codec.rs +0 -0
  300. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/columnar.rs +0 -0
  301. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/envelope.rs +0 -0
  302. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/errors.rs +0 -0
  303. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/format.rs +0 -0
  304. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/lib.rs +0 -0
  305. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/options.rs +0 -0
  306. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/tests.rs +0 -0
  307. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/transform.rs +0 -0
  308. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/src/view.rs +0 -0
  309. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-snapshot/tests/error_messages.rs +0 -0
  310. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/Cargo.toml +0 -0
  311. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/codec.rs +0 -0
  312. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/intern.rs +0 -0
  313. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/lock_table.rs +0 -0
  314. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/chunked_vec.rs +0 -0
  315. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/constraint_catalog.rs +0 -0
  316. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/constraint_enforce.rs +0 -0
  317. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/cow.rs +0 -0
  318. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/entity_index_store.rs +0 -0
  319. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/graph.rs +0 -0
  320. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/hnsw.rs +0 -0
  321. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/impls.rs +0 -0
  322. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/index_catalog.rs +0 -0
  323. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/mem_report.rs +0 -0
  324. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/mod.rs +0 -0
  325. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/point_index.rs +0 -0
  326. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/property_index.rs +0 -0
  327. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/secondary_index_maintenance.rs +0 -0
  328. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/snapshot.rs +0 -0
  329. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/sorted_property_index.rs +0 -0
  330. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/stats.rs +0 -0
  331. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/tests.rs +0 -0
  332. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/text_index.rs +0 -0
  333. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/memory/vector_index.rs +0 -0
  334. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/mutation.rs +0 -0
  335. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/snapshot.rs +0 -0
  336. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/traits.rs +0 -0
  337. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/binary/mod.rs +0 -0
  338. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/binary/tests.rs +0 -0
  339. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/binary/traits.rs +0 -0
  340. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/binary/types.rs +0 -0
  341. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/graph.rs +0 -0
  342. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/property_map.rs +0 -0
  343. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/property_value.rs +0 -0
  344. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/spatial/distance.rs +0 -0
  345. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/spatial/point.rs +0 -0
  346. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/spatial/srid.rs +0 -0
  347. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/spatial/tests.rs +0 -0
  348. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/temporal/calendar.rs +0 -0
  349. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/temporal/date.rs +0 -0
  350. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/temporal/datetime.rs +0 -0
  351. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/temporal/duration.rs +0 -0
  352. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/temporal/format.rs +0 -0
  353. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/temporal/mod.rs +0 -0
  354. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/temporal/parsing.rs +0 -0
  355. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/temporal/time.rs +0 -0
  356. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/temporal/zone.rs +0 -0
  357. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/vector/build.rs +0 -0
  358. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/vector/mod.rs +0 -0
  359. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/vector/similarity.rs +0 -0
  360. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/vector/tests.rs +0 -0
  361. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/src/types/vector/types.rs +0 -0
  362. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-store/tests/error_messages.rs +0 -0
  363. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/Cargo.toml +0 -0
  364. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/codec/decode.rs +0 -0
  365. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/codec/encode.rs +0 -0
  366. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/codec/format.rs +0 -0
  367. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/codec/mod.rs +0 -0
  368. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/codec/tests.rs +0 -0
  369. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/config.rs +0 -0
  370. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/dir.rs +0 -0
  371. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/errors.rs +0 -0
  372. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/history.rs +0 -0
  373. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/io.rs +0 -0
  374. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/lib.rs +0 -0
  375. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/lock.rs +0 -0
  376. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/lsn.rs +0 -0
  377. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/record.rs +0 -0
  378. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/recorder/errors.rs +0 -0
  379. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/recorder/mirror.rs +0 -0
  380. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/recorder/mod.rs +0 -0
  381. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/recorder/recorder.rs +0 -0
  382. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/recorder/tests.rs +0 -0
  383. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/replay.rs +0 -0
  384. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/segment.rs +0 -0
  385. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/testing.rs +0 -0
  386. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/wal/group_flusher.rs +0 -0
  387. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/wal/mod.rs +0 -0
  388. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/wal/tests.rs +0 -0
  389. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/src/wal/wal.rs +0 -0
  390. {lora_python-0.19.0 → lora_python-0.20.0}/crates/lora-wal/tests/error_messages.rs +0 -0
  391. {lora_python-0.19.0 → lora_python-0.20.0}/python/lora_python/__init__.py +0 -0
  392. {lora_python-0.19.0 → lora_python-0.20.0}/python/lora_python/_native.pyi +0 -0
  393. {lora_python-0.19.0 → lora_python-0.20.0}/python/lora_python/py.typed +0 -0
  394. {lora_python-0.19.0 → lora_python-0.20.0}/python/lora_python/types.py +0 -0
@@ -854,7 +854,7 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
854
854
 
855
855
  [[package]]
856
856
  name = "lora-analyzer"
857
- version = "0.19.0"
857
+ version = "0.20.0"
858
858
  dependencies = [
859
859
  "lora-ast",
860
860
  "lora-builtins-meta",
@@ -865,14 +865,14 @@ dependencies = [
865
865
 
866
866
  [[package]]
867
867
  name = "lora-ast"
868
- version = "0.19.0"
868
+ version = "0.20.0"
869
869
  dependencies = [
870
870
  "smallvec 2.0.0-alpha.12",
871
871
  ]
872
872
 
873
873
  [[package]]
874
874
  name = "lora-binding-buffer"
875
- version = "0.19.0"
875
+ version = "0.20.0"
876
876
  dependencies = [
877
877
  "lora-database",
878
878
  "lora-store",
@@ -880,11 +880,11 @@ dependencies = [
880
880
 
881
881
  [[package]]
882
882
  name = "lora-builtins-meta"
883
- version = "0.19.0"
883
+ version = "0.20.0"
884
884
 
885
885
  [[package]]
886
886
  name = "lora-compiler"
887
- version = "0.19.0"
887
+ version = "0.20.0"
888
888
  dependencies = [
889
889
  "lora-analyzer",
890
890
  "lora-ast",
@@ -893,7 +893,7 @@ dependencies = [
893
893
 
894
894
  [[package]]
895
895
  name = "lora-database"
896
- version = "0.19.0"
896
+ version = "0.20.0"
897
897
  dependencies = [
898
898
  "anyhow",
899
899
  "chacha20poly1305",
@@ -918,7 +918,7 @@ dependencies = [
918
918
 
919
919
  [[package]]
920
920
  name = "lora-executor"
921
- version = "0.19.0"
921
+ version = "0.20.0"
922
922
  dependencies = [
923
923
  "blake3",
924
924
  "crc32fast",
@@ -941,7 +941,7 @@ dependencies = [
941
941
 
942
942
  [[package]]
943
943
  name = "lora-ffi"
944
- version = "0.19.0"
944
+ version = "0.20.0"
945
945
  dependencies = [
946
946
  "anyhow",
947
947
  "lora-binding-buffer",
@@ -953,7 +953,7 @@ dependencies = [
953
953
 
954
954
  [[package]]
955
955
  name = "lora-io"
956
- version = "0.19.0"
956
+ version = "0.20.0"
957
957
  dependencies = [
958
958
  "lora-executor",
959
959
  "lora-store",
@@ -964,7 +964,7 @@ dependencies = [
964
964
 
965
965
  [[package]]
966
966
  name = "lora-node"
967
- version = "0.19.0"
967
+ version = "0.20.0"
968
968
  dependencies = [
969
969
  "anyhow",
970
970
  "lora-binding-buffer",
@@ -979,7 +979,7 @@ dependencies = [
979
979
 
980
980
  [[package]]
981
981
  name = "lora-parser"
982
- version = "0.19.0"
982
+ version = "0.20.0"
983
983
  dependencies = [
984
984
  "lora-ast",
985
985
  "pest",
@@ -990,7 +990,7 @@ dependencies = [
990
990
 
991
991
  [[package]]
992
992
  name = "lora-python"
993
- version = "0.19.0"
993
+ version = "0.20.0"
994
994
  dependencies = [
995
995
  "anyhow",
996
996
  "lora-binding-buffer",
@@ -1003,7 +1003,7 @@ dependencies = [
1003
1003
 
1004
1004
  [[package]]
1005
1005
  name = "lora-query-wasm"
1006
- version = "0.19.0"
1006
+ version = "0.20.0"
1007
1007
  dependencies = [
1008
1008
  "console_error_panic_hook",
1009
1009
  "js-sys",
@@ -1017,7 +1017,7 @@ dependencies = [
1017
1017
 
1018
1018
  [[package]]
1019
1019
  name = "lora-server"
1020
- version = "0.19.0"
1020
+ version = "0.20.0"
1021
1021
  dependencies = [
1022
1022
  "anyhow",
1023
1023
  "axum",
@@ -1032,7 +1032,7 @@ dependencies = [
1032
1032
 
1033
1033
  [[package]]
1034
1034
  name = "lora-snapshot"
1035
- version = "0.19.0"
1035
+ version = "0.20.0"
1036
1036
  dependencies = [
1037
1037
  "argon2",
1038
1038
  "blake3",
@@ -1047,7 +1047,7 @@ dependencies = [
1047
1047
 
1048
1048
  [[package]]
1049
1049
  name = "lora-store"
1050
- version = "0.19.0"
1050
+ version = "0.20.0"
1051
1051
  dependencies = [
1052
1052
  "crc32fast",
1053
1053
  "jiff",
@@ -1062,7 +1062,7 @@ dependencies = [
1062
1062
 
1063
1063
  [[package]]
1064
1064
  name = "lora-wal"
1065
- version = "0.19.0"
1065
+ version = "0.20.0"
1066
1066
  dependencies = [
1067
1067
  "crc32fast",
1068
1068
  "lora-store",
@@ -1072,7 +1072,7 @@ dependencies = [
1072
1072
 
1073
1073
  [[package]]
1074
1074
  name = "lora-wasm"
1075
- version = "0.19.0"
1075
+ version = "0.20.0"
1076
1076
  dependencies = [
1077
1077
  "anyhow",
1078
1078
  "console_error_panic_hook",
@@ -1088,7 +1088,7 @@ dependencies = [
1088
1088
 
1089
1089
  [[package]]
1090
1090
  name = "lora_ruby"
1091
- version = "0.19.0"
1091
+ version = "0.20.0"
1092
1092
  dependencies = [
1093
1093
  "anyhow",
1094
1094
  "lora-database",
@@ -4,7 +4,7 @@ resolver = "2"
4
4
 
5
5
  [workspace.package]
6
6
  edition = "2021"
7
- version = "0.19.0"
7
+ version = "0.20.0"
8
8
  license = "BUSL-1.1"
9
9
  authors = ["LoraDB, Inc."]
10
10
  repository = "https://github.com/lora-db/lora"
@@ -15,18 +15,18 @@ rust-version = "1.87"
15
15
  # Internal crates — versions are kept in lockstep with [workspace.package].version
16
16
  # by `scripts/sync-versions.mjs`. Both `path` and `version` are set so that
17
17
  # `cargo publish` works (crates.io cannot resolve path-only deps).
18
- lora-ast = { path = "crates/lora-ast", version = "=0.19.0" }
19
- lora-parser = { path = "crates/lora-parser", version = "=0.19.0" }
20
- lora-builtins-meta = { path = "crates/lora-builtins-meta", version = "=0.19.0" }
21
- lora-analyzer = { path = "crates/lora-analyzer", version = "=0.19.0" }
22
- lora-compiler = { path = "crates/lora-compiler", version = "=0.19.0" }
23
- lora-store = { path = "crates/lora-store", version = "=0.19.0" }
24
- lora-snapshot = { path = "crates/lora-snapshot", version = "=0.19.0", default-features = false }
25
- lora-io = { path = "crates/lora-io", version = "=0.19.0" }
26
- lora-wal = { path = "crates/lora-wal", version = "=0.19.0" }
27
- lora-executor = { path = "crates/lora-executor", version = "=0.19.0", default-features = false }
28
- lora-database = { path = "crates/lora-database", version = "=0.19.0" }
29
- lora-binding-buffer = { path = "crates/bindings/lora-binding-buffer", version = "=0.19.0" }
18
+ lora-ast = { path = "crates/lora-ast", version = "=0.20.0" }
19
+ lora-parser = { path = "crates/lora-parser", version = "=0.20.0" }
20
+ lora-builtins-meta = { path = "crates/lora-builtins-meta", version = "=0.20.0" }
21
+ lora-analyzer = { path = "crates/lora-analyzer", version = "=0.20.0" }
22
+ lora-compiler = { path = "crates/lora-compiler", version = "=0.20.0" }
23
+ lora-store = { path = "crates/lora-store", version = "=0.20.0" }
24
+ lora-snapshot = { path = "crates/lora-snapshot", version = "=0.20.0", default-features = false }
25
+ lora-io = { path = "crates/lora-io", version = "=0.20.0" }
26
+ lora-wal = { path = "crates/lora-wal", version = "=0.20.0" }
27
+ lora-executor = { path = "crates/lora-executor", version = "=0.20.0", default-features = false }
28
+ lora-database = { path = "crates/lora-database", version = "=0.20.0" }
29
+ lora-binding-buffer = { path = "crates/bindings/lora-binding-buffer", version = "=0.20.0" }
30
30
 
31
31
  # External crates.
32
32
  anyhow = "1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lora-python
3
- Version: 0.19.0
3
+ Version: 0.20.0
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Programming Language :: Python :: 3.8
@@ -7,10 +7,10 @@
7
7
  //! is exhausted or dropped, and that lock guard must be released on the
8
8
  //! thread that took it, while a host may pull and drop the stream from
9
9
  //! any thread. The stream therefore lives on an actor thread that opens
10
- //! it, pulls one row per request and drops it. Actor threads are pooled,
11
- //! and a request and its reply spin briefly before parking, so a stream
12
- //! drained in a loop does not pay a thread start per open or a park and
13
- //! wake-up per row.
10
+ //! it, sends its rows in chunks (reading one chunk ahead, without
11
+ //! committing) and drops it. Actor threads are pooled, and a request and
12
+ //! its reply spin briefly before parking, so a stream drained in a loop
13
+ //! pays neither a thread start per open nor a round trip per row.
14
14
 
15
15
  use std::collections::HashMap;
16
16
  use std::hash::{BuildHasherDefault, Hasher};
@@ -116,6 +116,31 @@ mod actor {
116
116
  type Db = Arc<Database<InMemoryGraph>>;
117
117
  type Pulled<T, E> = Result<Option<T>, E>;
118
118
 
119
+ /// Most rows the actor pulls for one reply.
120
+ const CHUNK_ROWS: usize = 256;
121
+ /// About how long the actor pulls for one reply before sending what it
122
+ /// has: long enough to spread a round trip over many rows, short
123
+ /// enough that the first rows of a slow query arrive promptly.
124
+ const CHUNK_TIME: Duration = Duration::from_micros(50);
125
+
126
+ /// How a reply's rows end.
127
+ enum Tail<E> {
128
+ /// More rows may follow: ask again.
129
+ More,
130
+ /// No rows remain; the writes are staged, not committed. The next
131
+ /// request commits.
132
+ Drained,
133
+ /// The stream is gone, committed (`Ok`) or rolled back (`Err`),
134
+ /// and the writer lock released.
135
+ Done(Result<(), E>),
136
+ }
137
+
138
+ /// One reply: the next rows, then how they end.
139
+ type Chunk<T, E> = (Vec<T>, Tail<E>);
140
+
141
+ /// What the actor reports once it opened the stream (or failed to).
142
+ type Opened<T, E> = Result<(Vec<String>, Chunk<T, E>), E>;
143
+
119
144
  /// [`WriteStream`]s started and not yet done (their actor may hold or
120
145
  /// wait for the writer lock), process-wide.
121
146
  static ACTIVE: AtomicUsize = AtomicUsize::new(0);
@@ -144,13 +169,22 @@ mod actor {
144
169
  /// A mutating stream on its actor thread. Pull it and drop it on any
145
170
  /// thread; dropping an unfinished one rolls it back and releases the
146
171
  /// writer lock before `drop` returns.
172
+ ///
173
+ /// The actor sends rows in chunks and reads one chunk ahead of the
174
+ /// consumer, pulling with [`lora_database::QueryStream::pull`], which
175
+ /// does not commit at the end. It commits only when the consumer asks
176
+ /// for the row after the last one, so a stream abandoned before that
177
+ /// still rolls back.
147
178
  pub struct WriteStream<T, E> {
148
179
  columns: Vec<String>,
180
+ /// Rows received and not yet handed out.
181
+ rows: std::vec::IntoIter<T>,
182
+ /// How the received rows end.
183
+ tail: Tail<E>,
149
184
  requests: Option<Sender<()>>,
150
- replies: Receiver<Pulled<T, E>>,
185
+ replies: Receiver<Chunk<T, E>>,
151
186
  /// Disconnects once the actor has dropped the stream.
152
187
  done: Receiver<()>,
153
- ended: bool,
154
188
  }
155
189
 
156
190
  impl<T, E> WriteStream<T, E>
@@ -185,8 +219,8 @@ mod actor {
185
219
  F: FnMut(Row) -> Result<T, E> + Send + 'static,
186
220
  {
187
221
  let (requests, inbox) = mpsc::channel::<()>();
188
- let (reply, replies) = mpsc::channel::<Pulled<T, E>>();
189
- let (opened_tx, opened) = mpsc::sync_channel::<Result<Vec<String>, E>>(1);
222
+ let (reply, replies) = mpsc::channel::<Chunk<T, E>>();
223
+ let (opened_tx, opened) = mpsc::sync_channel::<Opened<T, E>>(1);
190
224
  let (done_tx, done) = mpsc::channel::<()>();
191
225
  let active = Active::enter();
192
226
  let job = move || {
@@ -204,31 +238,55 @@ mod actor {
204
238
  return;
205
239
  }
206
240
  };
207
- if opened_tx.send(Ok(stream.columns().to_vec())).is_err() {
241
+ let columns = stream.columns().to_vec();
242
+ // The first rows travel with the open.
243
+ let chunk = pull_chunk(&mut stream, &mut map);
244
+ let mut drained = matches!(chunk.1, Tail::Drained);
245
+ if let Tail::Done(_) = chunk.1 {
246
+ // An error: roll back and release the writer lock
247
+ // before the caller hears of it.
248
+ drop(stream);
249
+ let _ = opened_tx.send(Ok((columns, chunk)));
250
+ return;
251
+ }
252
+ if opened_tx.send(Ok((columns, chunk))).is_err() {
208
253
  // Nobody waits for it any more: roll back.
209
254
  return;
210
255
  }
211
- while recv(&inbox).is_ok() {
212
- let pulled = match stream.next_row() {
213
- Ok(Some(row)) => map(row).map(Some),
214
- Ok(None) => Ok(None),
215
- Err(e) => Err(E::from(LoraError::from_anyhow(e))),
216
- };
217
- if matches!(pulled, Ok(Some(_))) {
218
- if reply.send(pulled).is_err() {
219
- return;
256
+ loop {
257
+ // Read the next chunk while the caller consumes the
258
+ // last one. Once drained, the next request commits.
259
+ let chunk = (!drained).then(|| pull_chunk(&mut stream, &mut map));
260
+ if let Some((_, Tail::Done(_))) = chunk {
261
+ // An error: roll back and release the writer lock
262
+ // at once; the caller hears of it after the rows
263
+ // before it.
264
+ drop(stream);
265
+ if recv(&inbox).is_ok() {
266
+ let _ = reply.send(chunk.expect("chunk checked above"));
220
267
  }
221
- } else {
222
- // End or error: finish the stream (commit or roll
223
- // back) and release the writer lock before the
224
- // caller hears of it.
268
+ return;
269
+ }
270
+ if recv(&inbox).is_err() {
271
+ // The handle was dropped: `stream` drops here,
272
+ // rolling back.
273
+ return;
274
+ }
275
+ let Some(chunk) = chunk else {
276
+ let committed = stream
277
+ .finish()
278
+ .map_err(|e| E::from(LoraError::from_anyhow(e)));
279
+ // Release the writer lock before the caller hears
280
+ // of the commit.
225
281
  drop(stream);
226
- let _ = reply.send(pulled);
282
+ let _ = reply.send((Vec::new(), Tail::Done(committed)));
283
+ return;
284
+ };
285
+ drained = matches!(chunk.1, Tail::Drained);
286
+ if reply.send(chunk).is_err() {
227
287
  return;
228
288
  }
229
289
  }
230
- // The handle was dropped: `stream` drops here, rolling back
231
- // if it was not exhausted.
232
290
  };
233
291
  run_pooled(Box::new(job))
234
292
  .map_err(|e| E::from(internal(format!("could not start stream thread: {e}"))))?;
@@ -245,21 +303,62 @@ mod actor {
245
303
  /// Pull the next row: `None` at the end (the writes are then
246
304
  /// committed). An error rolls the writes back. Both end the
247
305
  /// stream; later pulls report the end.
306
+ #[inline]
248
307
  pub fn next_row(&mut self) -> Pulled<T, E> {
249
- if self.ended {
250
- return Ok(None);
308
+ if let Some(row) = self.rows.next() {
309
+ return Ok(Some(row));
310
+ }
311
+ self.refill()
312
+ }
313
+
314
+ /// Out of received rows: finish per the tail, or ask the actor for
315
+ /// more (or, once drained, to commit).
316
+ #[cold]
317
+ fn refill(&mut self) -> Pulled<T, E> {
318
+ loop {
319
+ match std::mem::replace(&mut self.tail, Tail::Done(Ok(()))) {
320
+ Tail::Done(result) => return result.map(|()| None),
321
+ Tail::More | Tail::Drained => {}
322
+ }
323
+ let closed = || E::from(internal("query stream thread exited".into()));
324
+ let sent = self.requests.as_ref().map(|requests| requests.send(()));
325
+ if !matches!(sent, Some(Ok(()))) {
326
+ return Err(closed());
327
+ }
328
+ let Ok((rows, tail)) = recv(&self.replies) else {
329
+ return Err(closed());
330
+ };
331
+ self.rows = rows.into_iter();
332
+ self.tail = tail;
333
+ if let Some(row) = self.rows.next() {
334
+ return Ok(Some(row));
335
+ }
251
336
  }
252
- let closed = || E::from(internal("query stream thread exited".into()));
253
- let sent = self.requests.as_ref().map(|requests| requests.send(()));
254
- if !matches!(sent, Some(Ok(()))) {
255
- self.ended = true;
256
- return Err(closed());
337
+ }
338
+ }
339
+
340
+ /// Pull up to [`CHUNK_ROWS`] rows, or for about [`CHUNK_TIME`], without
341
+ /// committing. On an error the stream has rolled back.
342
+ fn pull_chunk<T, E, F>(stream: &mut lora_database::QueryStream<'_>, map: &mut F) -> Chunk<T, E>
343
+ where
344
+ E: From<LoraError>,
345
+ F: FnMut(Row) -> Result<T, E>,
346
+ {
347
+ let start = Instant::now();
348
+ let mut rows = Vec::new();
349
+ loop {
350
+ let row = match stream.pull() {
351
+ Ok(Some(row)) => row,
352
+ Ok(None) => return (rows, Tail::Drained),
353
+ Err(e) => return (rows, Tail::Done(Err(E::from(LoraError::from_anyhow(e))))),
354
+ };
355
+ match map(row) {
356
+ Ok(row) => rows.push(row),
357
+ Err(e) => return (rows, Tail::Done(Err(e))),
257
358
  }
258
- let pulled = recv(&self.replies).map_err(|_| closed()).and_then(|p| p);
259
- if !matches!(pulled, Ok(Some(_))) {
260
- self.ended = true;
359
+ if rows.len() >= CHUNK_ROWS || (rows.len() % 16 == 0 && start.elapsed() >= CHUNK_TIME) {
360
+ return (rows, Tail::More);
261
361
  }
262
- pulled
263
362
  }
264
363
  }
265
364
 
@@ -268,10 +367,10 @@ mod actor {
268
367
  /// has opened it.
269
368
  pub struct OpeningStream<T, E> {
270
369
  parts: Option<Parts<T, E>>,
271
- opened: Receiver<Result<Vec<String>, E>>,
370
+ opened: Receiver<Opened<T, E>>,
272
371
  }
273
372
 
274
- type Parts<T, E> = (Sender<()>, Receiver<Pulled<T, E>>, Receiver<()>);
373
+ type Parts<T, E> = (Sender<()>, Receiver<Chunk<T, E>>, Receiver<()>);
275
374
 
276
375
  impl<T, E> OpeningStream<T, E>
277
376
  where
@@ -296,9 +395,9 @@ mod actor {
296
395
 
297
396
  fn finish(
298
397
  mut self,
299
- opened: Result<Result<Vec<String>, E>, RecvError>,
398
+ opened: Result<Opened<T, E>, RecvError>,
300
399
  ) -> Result<WriteStream<T, E>, E> {
301
- let columns =
400
+ let (columns, (rows, tail)) =
302
401
  opened.map_err(|_| E::from(internal("stream thread exited".into())))??;
303
402
  let (requests, replies, done) = self
304
403
  .parts
@@ -306,18 +405,19 @@ mod actor {
306
405
  .ok_or_else(|| E::from(internal("stream already opened".into())))?;
307
406
  Ok(WriteStream {
308
407
  columns,
408
+ rows: rows.into_iter(),
409
+ tail,
309
410
  requests: Some(requests),
310
411
  replies,
311
412
  done,
312
- ended: false,
313
413
  })
314
414
  }
315
415
  }
316
416
 
317
417
  impl<T, E> Drop for WriteStream<T, E> {
318
418
  /// Stop the actor and wait for it to drop the stream (rolling back
319
- /// an unfinished one). The actor is idle between pulls, so this is
320
- /// prompt.
419
+ /// an unfinished one). The actor pulls at most one chunk between
420
+ /// requests, so this is prompt.
321
421
  fn drop(&mut self) {
322
422
  self.requests.take();
323
423
  let _ = recv(&self.done);
@@ -11,9 +11,10 @@
11
11
  //! dropped off its thread, and with it the writer lock, hanging every later
12
12
  //! write). So a mutating stream lives on a dedicated thread (an actor, a
13
13
  //! pooled thread from `lora_binding_buffer::stream::WriteStream`): the
14
- //! thread opens the stream, pulls a row per request, and drops the stream
15
- //! (committing an exhausted one, rolling back an unfinished one) before it
16
- //! is done. Once open, the actor waits only for its handle's requests and
14
+ //! thread opens the stream, sends its rows in chunks, reading one chunk
15
+ //! ahead without committing, and drops the stream (committing once the
16
+ //! caller has pulled past the last row, rolling back an unfinished one)
17
+ //! before it is done. Once open, the actor waits only for its handle's requests and
17
18
  //! never needs the GIL, so a request is always answered promptly.
18
19
  //!
19
20
  //! Whether a query streams as a write comes from a per-database
@@ -533,6 +533,50 @@ def test_stream_and_transaction_helpers() -> None:
533
533
  ]
534
534
 
535
535
 
536
+ def _count(db: Database, label: str) -> int:
537
+ return db.execute(f"MATCH (n:{label}) RETURN count(n) AS c")["rows"][0]["c"]
538
+
539
+
540
+ def test_mutating_stream_commits_only_at_its_end() -> None:
541
+ # Many rows, so the native side sends several chunks ahead of the
542
+ # iteration; the writes commit only once the iteration reaches the end.
543
+ db = Database.create()
544
+ query = "UNWIND list.range(1, 2000) AS i CREATE (:Chunked {i: i}) RETURN i"
545
+ assert [row["i"] for row in db.stream(query)] == list(range(1, 2001))
546
+ assert _count(db, "Chunked") == 2000
547
+
548
+ # Every row read, but not the end: closing rolls back.
549
+ stream = db.stream(query.replace("Chunked", "AllButEnd"))
550
+ assert [next(stream)["i"] for _ in range(2000)] == list(range(1, 2001))
551
+ stream.close()
552
+ assert _count(db, "AllButEnd") == 0
553
+
554
+ # Abandoned mid-way, past the first chunk: rolls back and frees the lock.
555
+ stream = db.stream(query.replace("Chunked", "Abandoned"))
556
+ for _ in range(700):
557
+ next(stream)
558
+ del stream
559
+ assert _count(db, "Abandoned") == 0
560
+ db.execute("CREATE (:AfterAbandon)")
561
+ assert _count(db, "AfterAbandon") == 1
562
+
563
+
564
+ def test_mutating_stream_error_mid_stream_rolls_back() -> None:
565
+ # A query ending in a write streams row by row: the duplicate fails
566
+ # after 499 nodes were created, on the first pull.
567
+ db = Database.create()
568
+ db.execute("CREATE CONSTRAINT failing_id FOR (n:Failing) REQUIRE n.id IS UNIQUE")
569
+ xs = list(range(1, 600))
570
+ xs[499] = 1
571
+ stream = db.stream("UNWIND $xs AS x CREATE (:Failing {id: x})", {"xs": xs})
572
+ with pytest.raises(LoraQueryError):
573
+ next(stream)
574
+ assert list(stream) == []
575
+ assert _count(db, "Failing") == 0
576
+ db.execute("CREATE (:AfterError)")
577
+ assert _count(db, "AfterError") == 1
578
+
579
+
536
580
  def test_is_vector_returns_false_for_non_vectors() -> None:
537
581
  from lora_python import is_vector
538
582
 
@@ -12,7 +12,7 @@ pub use logical::{
12
12
  Aggregation, Argument, Create, Delete, Expand, Filter, Foreach, Limit, LogicalOp, LogicalPlan,
13
13
  Merge, NodeByPointScan, NodeByPropertyRangeScan, NodeByPropertyScan, NodeByTextScan, NodeScan,
14
14
  OptionalMatch, PathBuild, PlanNodeId, PointPredicate, Projection, RelByPointScan,
15
- RelByPropertyRangeScan, RelByTextScan, Remove, Set, Sort, TextPredicate, Unwind,
15
+ RelByPropertyRangeScan, RelByTextScan, Remove, Set, Sort, SortLimit, TextPredicate, Unwind,
16
16
  };
17
17
  pub use optimizer::Optimizer;
18
18
  pub use physical::{
@@ -280,6 +280,17 @@ pub struct Sort {
280
280
  /// Optional upper bound for rows the sort must retain because a parent
281
281
  /// LIMIT will discard everything after this many sorted rows.
282
282
  pub top_k: Option<usize>,
283
+ /// The parent LIMIT's `SKIP` / `LIMIT` expressions when they are not
284
+ /// literals (`LIMIT $n`): the executor evaluates them once per run and
285
+ /// keeps only `skip + limit` rows, like a static [`Sort::top_k`].
286
+ pub limit: Option<SortLimit>,
287
+ }
288
+
289
+ /// A parent LIMIT's row bound, evaluated at run time (see [`Sort::limit`]).
290
+ #[derive(Debug, Clone)]
291
+ pub struct SortLimit {
292
+ pub skip: Option<ResolvedExpr>,
293
+ pub limit: ResolvedExpr,
283
294
  }
284
295
 
285
296
  #[derive(Debug, Clone)]
@@ -130,12 +130,32 @@ impl Optimizer {
130
130
  fn annotate_top_k_sorts(&self, plan: &mut LogicalPlan) {
131
131
  let len = plan.nodes.len();
132
132
  for i in 0..len {
133
- let Some((input, bound)) = limit_sort_bound(&plan.nodes[i]) else {
133
+ let LogicalOp::Limit(limit) = &plan.nodes[i] else {
134
134
  continue;
135
135
  };
136
-
137
- if let Some(sort) = sort_op_mut(&mut plan.nodes[input]) {
138
- sort.top_k = merge_top_k_bound(sort.top_k, bound);
136
+ let input = limit.input;
137
+ match limit_sort_bound(&plan.nodes[i]) {
138
+ Some((_, bound)) => {
139
+ if let Some(sort) = sort_op_mut(&mut plan.nodes[input]) {
140
+ sort.top_k = merge_top_k_bound(sort.top_k, bound);
141
+ }
142
+ }
143
+ // `LIMIT $n`: bound the sort with the same expressions,
144
+ // evaluated once per run.
145
+ None => {
146
+ let Some(limit_expr) = limit.limit.clone() else {
147
+ continue;
148
+ };
149
+ let skip = limit.skip.clone();
150
+ if let Some(sort) = sort_op_mut(&mut plan.nodes[input]) {
151
+ if sort.limit.is_none() {
152
+ sort.limit = Some(SortLimit {
153
+ skip,
154
+ limit: limit_expr,
155
+ });
156
+ }
157
+ }
158
+ }
139
159
  }
140
160
  }
141
161
  }
@@ -392,6 +412,7 @@ fn lower_logical_op(op: LogicalOp) -> PhysicalOp {
392
412
  input: sort.input,
393
413
  items: sort.items,
394
414
  top_k: sort.top_k,
415
+ limit: sort.limit,
395
416
  }),
396
417
 
397
418
  LogicalOp::Limit(limit) => PhysicalOp::Limit(LimitExec {
@@ -229,6 +229,9 @@ pub struct SortExec {
229
229
  pub items: Vec<ResolvedSortItem>,
230
230
  /// Optional upper bound for rows Sort must retain before a parent LIMIT.
231
231
  pub top_k: Option<usize>,
232
+ /// Run-time bound from a parent `LIMIT $n` (see
233
+ /// [`crate::logical::Sort::limit`]).
234
+ pub limit: Option<crate::logical::SortLimit>,
232
235
  }
233
236
 
234
237
  #[derive(Debug, Clone)]
@@ -357,6 +357,13 @@ fn describe(op: &PhysicalOp) -> PlanDescription {
357
357
  );
358
358
  if let Some(top_k) = n.top_k {
359
359
  d.insert("top_k".to_string(), top_k.to_string());
360
+ } else if let Some(bound) = &n.limit {
361
+ let limit = expr_str(&bound.limit);
362
+ let top_k = match &bound.skip {
363
+ Some(skip) => format!("{} + {limit}", expr_str(skip)),
364
+ None => limit,
365
+ };
366
+ d.insert("top_k".to_string(), top_k);
360
367
  }
361
368
  PlanDescription::with_children("Sort", d, vec![n.input])
362
369
  }