lora-python 0.11.5__tar.gz → 0.12.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 (313) hide show
  1. {lora_python-0.11.5 → lora_python-0.12.0}/Cargo.lock +19 -18
  2. {lora_python-0.11.5 → lora_python-0.12.0}/Cargo.toml +12 -12
  3. {lora_python-0.11.5 → lora_python-0.12.0}/PKG-INFO +1 -1
  4. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/fixtures.rs +75 -0
  5. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/query_implementations.rs +61 -1
  6. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/procedures.rs +102 -104
  7. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/schema.rs +115 -2
  8. lora_python-0.12.0/crates/lora-database/tests/vector_index.rs +1222 -0
  9. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/Cargo.toml +1 -0
  10. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/columnar.rs +36 -3
  11. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/format.rs +6 -1
  12. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/tests.rs +2 -0
  13. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/lib.rs +1 -1
  14. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/entity_index_store.rs +3 -0
  15. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/graph.rs +146 -22
  16. lora_python-0.12.0/crates/lora-store/src/memory/hnsw.rs +783 -0
  17. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/impls.rs +33 -2
  18. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/index_catalog.rs +10 -0
  19. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/mod.rs +3 -0
  20. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/point_index.rs +16 -1
  21. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/secondary_index_maintenance.rs +45 -0
  22. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/snapshot.rs +28 -0
  23. lora_python-0.12.0/crates/lora-store/src/memory/vector_index.rs +489 -0
  24. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/snapshot.rs +8 -1
  25. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/traits.rs +27 -2
  26. {lora_python-0.11.5 → lora_python-0.12.0}/pyproject.toml +1 -1
  27. lora_python-0.11.5/crates/lora-database/tests/vector_index.rs +0 -350
  28. {lora_python-0.11.5 → lora_python-0.12.0}/LICENSE +0 -0
  29. {lora_python-0.11.5 → lora_python-0.12.0}/README.md +0 -0
  30. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/.gitignore +0 -0
  31. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/Cargo.toml +0 -0
  32. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/LICENSE +0 -0
  33. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/README.md +0 -0
  34. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/build.rs +0 -0
  35. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/examples/async_demo.py +0 -0
  36. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/examples/basic.py +0 -0
  37. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/src/errors.rs +0 -0
  38. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/src/from_python.rs +0 -0
  39. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/src/lib.rs +0 -0
  40. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/src/to_python.rs +0 -0
  41. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/tests/test_async.py +0 -0
  42. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/tests/test_explain_profile.py +0 -0
  43. {lora_python-0.11.5 → lora_python-0.12.0}/crates/bindings/lora-python/tests/test_sync.py +0 -0
  44. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/Cargo.toml +0 -0
  45. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/analyzer/builtin_signatures.rs +0 -0
  46. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/analyzer/clauses.rs +0 -0
  47. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/analyzer/expressions.rs +0 -0
  48. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/analyzer/mod.rs +0 -0
  49. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/analyzer/patterns.rs +0 -0
  50. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/analyzer/state.rs +0 -0
  51. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/analyzer/tests.rs +0 -0
  52. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/errors.rs +0 -0
  53. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/lib.rs +0 -0
  54. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/resolved.rs +0 -0
  55. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/scope.rs +0 -0
  56. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/src/symbols.rs +0 -0
  57. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-analyzer/tests/error_messages.rs +0 -0
  58. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-ast/Cargo.toml +0 -0
  59. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-ast/src/ast.rs +0 -0
  60. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-ast/src/lib.rs +0 -0
  61. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-builtins-meta/Cargo.toml +0 -0
  62. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-builtins-meta/src/lib.rs +0 -0
  63. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-compiler/Cargo.toml +0 -0
  64. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-compiler/src/lib.rs +0 -0
  65. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-compiler/src/logical.rs +0 -0
  66. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-compiler/src/optimizer.rs +0 -0
  67. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-compiler/src/pattern.rs +0 -0
  68. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-compiler/src/physical.rs +0 -0
  69. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-compiler/src/plan_tree.rs +0 -0
  70. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-compiler/src/planner.rs +0 -0
  71. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/Cargo.toml +0 -0
  72. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/README.md +0 -0
  73. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/advanced.rs +0 -0
  74. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/concurrency_guard.rs +0 -0
  75. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/concurrent.rs +0 -0
  76. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/engine.rs +0 -0
  77. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/index_acceleration.rs +0 -0
  78. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/perf_smoke.rs +0 -0
  79. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/perf_smoke_baseline.json +0 -0
  80. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/realistic.rs +0 -0
  81. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/scale.rs +0 -0
  82. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/temporal_spatial.rs +0 -0
  83. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/benches/wal.rs +0 -0
  84. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/builder.rs +0 -0
  85. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/compile.rs +0 -0
  86. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/execute.rs +0 -0
  87. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/explain.rs +0 -0
  88. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/graph_api.rs +0 -0
  89. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/mod.rs +0 -0
  90. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/occ.rs +0 -0
  91. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/profile.rs +0 -0
  92. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/pull_mode.rs +0 -0
  93. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/replay.rs +0 -0
  94. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/row_projection.rs +0 -0
  95. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/show_pipeline.rs +0 -0
  96. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/stream.rs +0 -0
  97. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/database/write_guard.rs +0 -0
  98. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/durable_io.rs +0 -0
  99. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/error.rs +0 -0
  100. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/explain.rs +0 -0
  101. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/lib.rs +0 -0
  102. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/live_store.rs +0 -0
  103. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/named.rs +0 -0
  104. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/plan_cache.rs +0 -0
  105. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/snapshot/json.rs +0 -0
  106. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/snapshot/mod.rs +0 -0
  107. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/snapshot/store.rs +0 -0
  108. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/stream.rs +0 -0
  109. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/transaction.rs +0 -0
  110. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/wal/admin.rs +0 -0
  111. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/wal/archive/format.rs +0 -0
  112. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/wal/archive/lock.rs +0 -0
  113. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/wal/archive/platform.rs +0 -0
  114. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/wal/archive/worker.rs +0 -0
  115. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/wal/archive/workspace.rs +0 -0
  116. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/wal/archive.rs +0 -0
  117. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/wal/mod.rs +0 -0
  118. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/src/wal/write_scope.rs +0 -0
  119. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/advanced_queries.rs +0 -0
  120. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/aggregation.rs +0 -0
  121. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/backend_stub.rs +0 -0
  122. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/binary.rs +0 -0
  123. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/builtin_namespaces.rs +0 -0
  124. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/constraints.rs +0 -0
  125. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/create.rs +0 -0
  126. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/docs_examples.rs +0 -0
  127. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/error_messages.rs +0 -0
  128. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/errors.rs +0 -0
  129. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/explain_profile.rs +0 -0
  130. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/expressions.rs +0 -0
  131. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/foreach.rs +0 -0
  132. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/fulltext_index.rs +0 -0
  133. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/functions_extended.rs +0 -0
  134. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/index_acceleration.rs +0 -0
  135. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/invariants.rs +0 -0
  136. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/managed_snapshots.rs +0 -0
  137. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/match.rs +0 -0
  138. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/merge.rs +0 -0
  139. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/ordering.rs +0 -0
  140. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/parameters.rs +0 -0
  141. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/parser.rs +0 -0
  142. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/paths.rs +0 -0
  143. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/projection.rs +0 -0
  144. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/scale.rs +0 -0
  145. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/schema.rs +0 -0
  146. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/seeds.rs +0 -0
  147. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/snapshot.rs +0 -0
  148. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/spatial.rs +0 -0
  149. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/temporal.rs +0 -0
  150. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/test_helpers.rs +0 -0
  151. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/transactions.rs +0 -0
  152. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/types_advanced.rs +0 -0
  153. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/union.rs +0 -0
  154. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/unwind_ingestion.rs +0 -0
  155. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/update.rs +0 -0
  156. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/vectors.rs +0 -0
  157. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/wal.rs +0 -0
  158. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/where_clause.rs +0 -0
  159. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-database/tests/with.rs +0 -0
  160. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/Cargo.toml +0 -0
  161. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/errors.rs +0 -0
  162. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/binops.rs +0 -0
  163. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/bits_ns.rs +0 -0
  164. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/bytes_ns.rs +0 -0
  165. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/cast_ns.rs +0 -0
  166. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/crypto.rs +0 -0
  167. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/edge.rs +0 -0
  168. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/geo.rs +0 -0
  169. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/json_ns.rs +0 -0
  170. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/list.rs +0 -0
  171. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/map_ns.rs +0 -0
  172. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/math_ns.rs +0 -0
  173. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/mod.rs +0 -0
  174. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/node.rs +0 -0
  175. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/number.rs +0 -0
  176. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/path.rs +0 -0
  177. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/string_ns.rs +0 -0
  178. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/temporal.rs +0 -0
  179. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/text.rs +0 -0
  180. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/type_ns.rs +0 -0
  181. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/uuid_ns.rs +0 -0
  182. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/value.rs +0 -0
  183. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/builtins/vector_ns.rs +0 -0
  184. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/errors.rs +0 -0
  185. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/expr.rs +0 -0
  186. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/functions.rs +0 -0
  187. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/mod.rs +0 -0
  188. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/point.rs +0 -0
  189. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/regex.rs +0 -0
  190. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/eval/vector.rs +0 -0
  191. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/executor/aggregation.rs +0 -0
  192. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/executor/helpers.rs +0 -0
  193. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/executor/immutable.rs +0 -0
  194. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/executor/mod.rs +0 -0
  195. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/executor/mutable.rs +0 -0
  196. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/executor/optional.rs +0 -0
  197. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/executor/sort.rs +0 -0
  198. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/lib.rs +0 -0
  199. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/profile.rs +0 -0
  200. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/aggregate.rs +0 -0
  201. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/call_subquery.rs +0 -0
  202. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/columns.rs +0 -0
  203. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/context.rs +0 -0
  204. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/expand.rs +0 -0
  205. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/filter.rs +0 -0
  206. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/hydration.rs +0 -0
  207. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/mod.rs +0 -0
  208. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/mutable.rs +0 -0
  209. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/optional.rs +0 -0
  210. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/path.rs +0 -0
  211. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/projection.rs +0 -0
  212. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/scan.rs +0 -0
  213. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/shape.rs +0 -0
  214. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/sort.rs +0 -0
  215. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/source.rs +0 -0
  216. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/tests.rs +0 -0
  217. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/traits.rs +0 -0
  218. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/pull/union.rs +0 -0
  219. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/src/value.rs +0 -0
  220. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-executor/tests/error_messages.rs +0 -0
  221. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/Cargo.toml +0 -0
  222. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/cypher.pest +0 -0
  223. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/errors.rs +0 -0
  224. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/lib.rs +0 -0
  225. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/parser/clauses.rs +0 -0
  226. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/parser/expressions.rs +0 -0
  227. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/parser/literals.rs +0 -0
  228. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/parser/mod.rs +0 -0
  229. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/parser/patterns.rs +0 -0
  230. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/parser/query.rs +0 -0
  231. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/parser/schema.rs +0 -0
  232. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/parser/tests.rs +0 -0
  233. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/src/parser/util.rs +0 -0
  234. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-parser/tests/error_messages.rs +0 -0
  235. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/body.rs +0 -0
  236. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/codec.rs +0 -0
  237. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/envelope.rs +0 -0
  238. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/errors.rs +0 -0
  239. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/lib.rs +0 -0
  240. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/options.rs +0 -0
  241. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/transform.rs +0 -0
  242. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/src/view.rs +0 -0
  243. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-snapshot/tests/error_messages.rs +0 -0
  244. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/Cargo.toml +0 -0
  245. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/codec.rs +0 -0
  246. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/lock_table.rs +0 -0
  247. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/constraint_catalog.rs +0 -0
  248. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/constraint_enforce.rs +0 -0
  249. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/fulltext_index.rs +0 -0
  250. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/property_index.rs +0 -0
  251. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/sorted_property_index.rs +0 -0
  252. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/stats.rs +0 -0
  253. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/tests.rs +0 -0
  254. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/memory/text_index.rs +0 -0
  255. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/mutation.rs +0 -0
  256. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/binary/mod.rs +0 -0
  257. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/binary/tests.rs +0 -0
  258. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/binary/traits.rs +0 -0
  259. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/binary/types.rs +0 -0
  260. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/graph.rs +0 -0
  261. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/mod.rs +0 -0
  262. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/property_value.rs +0 -0
  263. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/spatial/distance.rs +0 -0
  264. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/spatial/mod.rs +0 -0
  265. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/spatial/point.rs +0 -0
  266. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/spatial/srid.rs +0 -0
  267. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/spatial/tests.rs +0 -0
  268. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/temporal/calendar.rs +0 -0
  269. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/temporal/date.rs +0 -0
  270. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/temporal/datetime.rs +0 -0
  271. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/temporal/duration.rs +0 -0
  272. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/temporal/format.rs +0 -0
  273. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/temporal/mod.rs +0 -0
  274. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/temporal/parsing.rs +0 -0
  275. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/temporal/time.rs +0 -0
  276. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/vector/build.rs +0 -0
  277. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/vector/mod.rs +0 -0
  278. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/vector/similarity.rs +0 -0
  279. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/vector/tests.rs +0 -0
  280. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/src/types/vector/types.rs +0 -0
  281. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-store/tests/error_messages.rs +0 -0
  282. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/Cargo.toml +0 -0
  283. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/codec/decode.rs +0 -0
  284. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/codec/encode.rs +0 -0
  285. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/codec/format.rs +0 -0
  286. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/codec/mod.rs +0 -0
  287. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/codec/tests.rs +0 -0
  288. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/config.rs +0 -0
  289. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/dir.rs +0 -0
  290. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/errors.rs +0 -0
  291. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/io.rs +0 -0
  292. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/lib.rs +0 -0
  293. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/lock.rs +0 -0
  294. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/lsn.rs +0 -0
  295. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/record.rs +0 -0
  296. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/recorder/errors.rs +0 -0
  297. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/recorder/mirror.rs +0 -0
  298. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/recorder/mod.rs +0 -0
  299. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/recorder/recorder.rs +0 -0
  300. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/recorder/tests.rs +0 -0
  301. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/replay.rs +0 -0
  302. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/segment.rs +0 -0
  303. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/testing.rs +0 -0
  304. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/wal/group_flusher.rs +0 -0
  305. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/wal/mod.rs +0 -0
  306. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/wal/tests.rs +0 -0
  307. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/src/wal/wal.rs +0 -0
  308. {lora_python-0.11.5 → lora_python-0.12.0}/crates/lora-wal/tests/error_messages.rs +0 -0
  309. {lora_python-0.11.5 → lora_python-0.12.0}/python/lora_python/__init__.py +0 -0
  310. {lora_python-0.11.5 → lora_python-0.12.0}/python/lora_python/_async.py +0 -0
  311. {lora_python-0.11.5 → lora_python-0.12.0}/python/lora_python/_native.pyi +0 -0
  312. {lora_python-0.11.5 → lora_python-0.12.0}/python/lora_python/py.typed +0 -0
  313. {lora_python-0.11.5 → lora_python-0.12.0}/python/lora_python/types.py +0 -0
@@ -773,7 +773,7 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
773
773
 
774
774
  [[package]]
775
775
  name = "lora-analyzer"
776
- version = "0.11.5"
776
+ version = "0.12.0"
777
777
  dependencies = [
778
778
  "lora-ast",
779
779
  "lora-builtins-meta",
@@ -784,14 +784,14 @@ dependencies = [
784
784
 
785
785
  [[package]]
786
786
  name = "lora-ast"
787
- version = "0.11.5"
787
+ version = "0.12.0"
788
788
  dependencies = [
789
789
  "smallvec 2.0.0-alpha.12",
790
790
  ]
791
791
 
792
792
  [[package]]
793
793
  name = "lora-binding-buffer"
794
- version = "0.11.5"
794
+ version = "0.12.0"
795
795
  dependencies = [
796
796
  "lora-database",
797
797
  "lora-store",
@@ -799,11 +799,11 @@ dependencies = [
799
799
 
800
800
  [[package]]
801
801
  name = "lora-builtins-meta"
802
- version = "0.11.5"
802
+ version = "0.12.0"
803
803
 
804
804
  [[package]]
805
805
  name = "lora-compiler"
806
- version = "0.11.5"
806
+ version = "0.12.0"
807
807
  dependencies = [
808
808
  "lora-analyzer",
809
809
  "lora-ast",
@@ -812,7 +812,7 @@ dependencies = [
812
812
 
813
813
  [[package]]
814
814
  name = "lora-database"
815
- version = "0.11.5"
815
+ version = "0.12.0"
816
816
  dependencies = [
817
817
  "anyhow",
818
818
  "chacha20poly1305",
@@ -836,7 +836,7 @@ dependencies = [
836
836
 
837
837
  [[package]]
838
838
  name = "lora-executor"
839
- version = "0.11.5"
839
+ version = "0.12.0"
840
840
  dependencies = [
841
841
  "blake3",
842
842
  "crc32fast",
@@ -859,7 +859,7 @@ dependencies = [
859
859
 
860
860
  [[package]]
861
861
  name = "lora-ffi"
862
- version = "0.11.5"
862
+ version = "0.12.0"
863
863
  dependencies = [
864
864
  "anyhow",
865
865
  "lora-binding-buffer",
@@ -871,7 +871,7 @@ dependencies = [
871
871
 
872
872
  [[package]]
873
873
  name = "lora-node"
874
- version = "0.11.5"
874
+ version = "0.12.0"
875
875
  dependencies = [
876
876
  "anyhow",
877
877
  "lora-binding-buffer",
@@ -886,7 +886,7 @@ dependencies = [
886
886
 
887
887
  [[package]]
888
888
  name = "lora-parser"
889
- version = "0.11.5"
889
+ version = "0.12.0"
890
890
  dependencies = [
891
891
  "lora-ast",
892
892
  "pest",
@@ -897,7 +897,7 @@ dependencies = [
897
897
 
898
898
  [[package]]
899
899
  name = "lora-python"
900
- version = "0.11.5"
900
+ version = "0.12.0"
901
901
  dependencies = [
902
902
  "anyhow",
903
903
  "lora-database",
@@ -909,7 +909,7 @@ dependencies = [
909
909
 
910
910
  [[package]]
911
911
  name = "lora-query-wasm"
912
- version = "0.11.5"
912
+ version = "0.12.0"
913
913
  dependencies = [
914
914
  "console_error_panic_hook",
915
915
  "js-sys",
@@ -923,7 +923,7 @@ dependencies = [
923
923
 
924
924
  [[package]]
925
925
  name = "lora-server"
926
- version = "0.11.5"
926
+ version = "0.12.0"
927
927
  dependencies = [
928
928
  "anyhow",
929
929
  "axum",
@@ -937,7 +937,7 @@ dependencies = [
937
937
 
938
938
  [[package]]
939
939
  name = "lora-snapshot"
940
- version = "0.11.5"
940
+ version = "0.12.0"
941
941
  dependencies = [
942
942
  "argon2",
943
943
  "blake3",
@@ -946,12 +946,13 @@ dependencies = [
946
946
  "getrandom",
947
947
  "lora-store",
948
948
  "serde",
949
+ "serde_json",
949
950
  "thiserror",
950
951
  ]
951
952
 
952
953
  [[package]]
953
954
  name = "lora-store"
954
- version = "0.11.5"
955
+ version = "0.12.0"
955
956
  dependencies = [
956
957
  "crc32fast",
957
958
  "js-sys",
@@ -962,7 +963,7 @@ dependencies = [
962
963
 
963
964
  [[package]]
964
965
  name = "lora-wal"
965
- version = "0.11.5"
966
+ version = "0.12.0"
966
967
  dependencies = [
967
968
  "crc32fast",
968
969
  "lora-store",
@@ -972,7 +973,7 @@ dependencies = [
972
973
 
973
974
  [[package]]
974
975
  name = "lora-wasm"
975
- version = "0.11.5"
976
+ version = "0.12.0"
976
977
  dependencies = [
977
978
  "anyhow",
978
979
  "console_error_panic_hook",
@@ -988,7 +989,7 @@ dependencies = [
988
989
 
989
990
  [[package]]
990
991
  name = "lora_ruby"
991
- version = "0.11.5"
992
+ version = "0.12.0"
992
993
  dependencies = [
993
994
  "anyhow",
994
995
  "lora-database",
@@ -4,7 +4,7 @@ resolver = "2"
4
4
 
5
5
  [workspace.package]
6
6
  edition = "2021"
7
- version = "0.11.5"
7
+ version = "0.12.0"
8
8
  license = "BUSL-1.1"
9
9
  authors = ["LoraDB, Inc."]
10
10
  repository = "https://github.com/lora-db/lora"
@@ -15,17 +15,17 @@ 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.11.5" }
19
- lora-parser = { path = "crates/lora-parser", version = "=0.11.5" }
20
- lora-builtins-meta = { path = "crates/lora-builtins-meta", version = "=0.11.5" }
21
- lora-analyzer = { path = "crates/lora-analyzer", version = "=0.11.5" }
22
- lora-compiler = { path = "crates/lora-compiler", version = "=0.11.5" }
23
- lora-store = { path = "crates/lora-store", version = "=0.11.5" }
24
- lora-snapshot = { path = "crates/lora-snapshot", version = "=0.11.5", default-features = false }
25
- lora-wal = { path = "crates/lora-wal", version = "=0.11.5" }
26
- lora-executor = { path = "crates/lora-executor", version = "=0.11.5", default-features = false }
27
- lora-database = { path = "crates/lora-database", version = "=0.11.5" }
28
- lora-binding-buffer = { path = "crates/bindings/lora-binding-buffer", version = "=0.11.5" }
18
+ lora-ast = { path = "crates/lora-ast", version = "=0.12.0" }
19
+ lora-parser = { path = "crates/lora-parser", version = "=0.12.0" }
20
+ lora-builtins-meta = { path = "crates/lora-builtins-meta", version = "=0.12.0" }
21
+ lora-analyzer = { path = "crates/lora-analyzer", version = "=0.12.0" }
22
+ lora-compiler = { path = "crates/lora-compiler", version = "=0.12.0" }
23
+ lora-store = { path = "crates/lora-store", version = "=0.12.0" }
24
+ lora-snapshot = { path = "crates/lora-snapshot", version = "=0.12.0", default-features = false }
25
+ lora-wal = { path = "crates/lora-wal", version = "=0.12.0" }
26
+ lora-executor = { path = "crates/lora-executor", version = "=0.12.0", default-features = false }
27
+ lora-database = { path = "crates/lora-database", version = "=0.12.0" }
28
+ lora-binding-buffer = { path = "crates/bindings/lora-binding-buffer", version = "=0.12.0" }
29
29
 
30
30
  # External crates.
31
31
  anyhow = "1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lora-python
3
- Version: 0.11.5
3
+ Version: 0.12.0
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Programming Language :: Python :: 3.8
@@ -22,10 +22,12 @@
22
22
  //! | `build_temporal_graph(n)` | `:Event` / `:FOLLOWS` | Events with date/time properties |
23
23
  //! | `build_spatial_graph(n)` | `:Location` / `:CONNECTS_TO` | Locations with point coords |
24
24
  //! | `build_recommendation_graph` | `:User`, `:Product` / `:BOUGHT`, etc | Bipartite user-product graph |
25
+ //! | `build_vector_graph(n, d, …)` | `:V` | Vector index k-NN benchmarks |
25
26
 
26
27
  use std::collections::BTreeMap;
27
28
 
28
29
  use lora_database::{Database, ExecuteOptions, InMemoryGraph, LoraValue, ResultFormat};
30
+ use lora_store::{LoraVector, RawCoordinate, VectorCoordinateType};
29
31
 
30
32
  // ---------------------------------------------------------------------------
31
33
  // Wrapper (mirrors TestDb from integration tests but without serde_json dep)
@@ -600,3 +602,76 @@ pub fn build_recommendation_graph(n_users: usize, n_products: usize) -> BenchDb
600
602
 
601
603
  db
602
604
  }
605
+
606
+ // ---------------------------------------------------------------------------
607
+ // Vector graph builder
608
+ // ---------------------------------------------------------------------------
609
+
610
+ /// Deterministic LCG → f32 in roughly [-1, 1). Stable across platforms,
611
+ /// no external dep. Used to seed vector fixtures so bench numbers are
612
+ /// comparable across runs.
613
+ fn vector_rng(seed: u64) -> impl FnMut() -> f32 {
614
+ let mut state = seed.wrapping_mul(0x9E37_79B9_7F4A_7C15).wrapping_add(1);
615
+ move || {
616
+ state = state
617
+ .wrapping_mul(6364136223846793005)
618
+ .wrapping_add(1442695040888963407);
619
+ let bits = (state >> 32) as u32 as i32;
620
+ bits as f32 / (i32::MAX as f32 + 1.0)
621
+ }
622
+ }
623
+
624
+ /// Build a graph of `n` `:V` nodes each carrying a `dim`-dimensional
625
+ /// FLOAT32 vector under property `e`, with a pre-created VECTOR index
626
+ /// `vidx`, similarity function `sim` (`"cosine"` or `"euclidean"`),
627
+ /// and index provider `provider` (`"flat"` or `"hnsw"`).
628
+ ///
629
+ /// Vectors are deterministic so the same fixture produces identical
630
+ /// content across runs. Used by `bench_vector_knn` to compare flat
631
+ /// vs HNSW throughput.
632
+ pub fn build_vector_graph(n: usize, dim: usize, sim: &str, provider: &str) -> BenchDb {
633
+ let db = BenchDb::with_capacity_hint(n, 0);
634
+ db.run(&format!(
635
+ "CREATE VECTOR INDEX vidx FOR (v:V) ON (v.e) \
636
+ OPTIONS {{indexConfig: {{ \
637
+ `vector.dimensions`: {dim}, \
638
+ `vector.similarity_function`: '{sim}', \
639
+ `vector.indexProvider`: '{provider}' \
640
+ }}}}",
641
+ ));
642
+
643
+ let mut rng = vector_rng(0x5EED);
644
+ // Each vector is dim * 4 bytes stored; intermediate RawCoordinate is
645
+ // 16 bytes per coord. Keep peak per-batch RSS bounded.
646
+ let batch = 1_000usize;
647
+ let mut i = 0usize;
648
+ while i < n {
649
+ let end = (i + batch).min(n);
650
+ let count = end - i;
651
+ let vecs: Vec<LoraValue> = (0..count)
652
+ .map(|_| {
653
+ let coords: Vec<RawCoordinate> = (0..dim)
654
+ .map(|_| RawCoordinate::Float(rng() as f64))
655
+ .collect();
656
+ LoraValue::Vector(
657
+ LoraVector::try_new(coords, dim as i64, VectorCoordinateType::Float32)
658
+ .expect("vector construction"),
659
+ )
660
+ })
661
+ .collect();
662
+ let params = BTreeMap::from([("vecs".to_string(), LoraValue::List(vecs))]);
663
+ db.run_with_params("UNWIND $vecs AS e CREATE (:V {e: e})", params);
664
+ i = end;
665
+ }
666
+ db
667
+ }
668
+
669
+ /// A single deterministic query vector with the given seed and dim.
670
+ pub fn build_vector_query(seed: u64, dim: usize) -> LoraVector {
671
+ let mut rng = vector_rng(seed);
672
+ let coords: Vec<RawCoordinate> = (0..dim)
673
+ .map(|_| RawCoordinate::Float(rng() as f64))
674
+ .collect();
675
+ LoraVector::try_new(coords, dim as i64, VectorCoordinateType::Float32)
676
+ .expect("vector construction")
677
+ }
@@ -595,6 +595,65 @@ fn bench_advanced_query_shapes(c: &mut Criterion) {
595
595
  group.finish();
596
596
  }
597
597
 
598
+ /// k-NN throughput across providers and scales.
599
+ ///
600
+ /// Flat: the Phase 1 baseline — every call scores every vector.
601
+ /// HNSW: the Phase 2 approximate index. d=384 matches a typical
602
+ /// sentence-transformer embedding. The 100k cases dominate total
603
+ /// bench time; restrict with e.g.
604
+ /// `cargo bench -- vector_knn/n_100000_cosine_hnsw` during iteration.
605
+ fn bench_vector_knn(c: &mut Criterion) {
606
+ let mut group = c.benchmark_group("query/vector_knn");
607
+ group.throughput(Throughput::Elements(1));
608
+ // 100k flat is ~50ms per query; 100k HNSW is sub-millisecond.
609
+ // Give criterion enough headroom on both ends without an
610
+ // intolerable suite runtime.
611
+ group.measurement_time(Duration::from_secs(5));
612
+ group.sample_size(20);
613
+
614
+ let dim = 384usize;
615
+ let k = 10usize;
616
+ let query = build_vector_query(0xDEAD_BEEF, dim);
617
+
618
+ // Flat at every scale (baseline curve).
619
+ for &n in &[1_000usize, 10_000, 100_000] {
620
+ for &sim in &["cosine", "euclidean"] {
621
+ let db = build_vector_graph(n, dim, sim, "flat");
622
+ let name = format!("n_{n}_{sim}_flat_k{k}_d{dim}");
623
+ group.bench_function(&name, |b| {
624
+ b.iter(|| {
625
+ let params =
626
+ BTreeMap::from([("q".to_string(), LoraValue::Vector(query.clone()))]);
627
+ run_params(
628
+ &db,
629
+ "CALL db.index.vector.queryNodes('vidx', 10, $q) YIELD node, score",
630
+ params,
631
+ );
632
+ });
633
+ });
634
+ }
635
+ }
636
+
637
+ // HNSW only at scales where the ANN structure pays for its
638
+ // construction cost. n=1k is dominated by procedure overhead and
639
+ // doesn't move on either backend; skip.
640
+ for &n in &[10_000usize, 100_000] {
641
+ let db = build_vector_graph(n, dim, "cosine", "hnsw");
642
+ let name = format!("n_{n}_cosine_hnsw_k{k}_d{dim}");
643
+ group.bench_function(&name, |b| {
644
+ b.iter(|| {
645
+ let params = BTreeMap::from([("q".to_string(), LoraValue::Vector(query.clone()))]);
646
+ run_params(
647
+ &db,
648
+ "CALL db.index.vector.queryNodes('vidx', 10, $q) YIELD node, score",
649
+ params,
650
+ );
651
+ });
652
+ });
653
+ }
654
+ group.finish();
655
+ }
656
+
598
657
  criterion_group! {
599
658
  name = benches;
600
659
  config = bench_config();
@@ -606,7 +665,8 @@ criterion_group! {
606
665
  bench_writes,
607
666
  bench_expressions_and_functions,
608
667
  bench_typed_values,
609
- bench_advanced_query_shapes
668
+ bench_advanced_query_shapes,
669
+ bench_vector_knn
610
670
  }
611
671
 
612
672
  criterion_main!(benches);
@@ -3,24 +3,25 @@
3
3
  //! These calls bypass the analyzer (which doesn't yet model standalone
4
4
  //! CALL). The cheap textual prefix router in [`is_procedure_call_text`]
5
5
  //! catches them, the parser produces a [`StandaloneCall`], and this
6
- //! module evaluates the procedure directly against the catalog + raw
7
- //! storage. The result is a flat row stream that the optional YIELD
8
- //! clause then projects.
6
+ //! module evaluates the procedure directly against the catalog + the
7
+ //! per-index backend exposed through [`GraphStorage::vector_search`].
8
+ //! The result is a flat row stream that the optional YIELD clause
9
+ //! then projects.
9
10
  //!
10
- //! kNN is computed with a flat scan: enumerate all label-matching
11
- //! entities, fetch the indexed property as [`LoraVector`], score, and
12
- //! keep the top `k` by descending similarity. Correctness only — a
13
- //! dedicated ANN structure is a follow-up.
11
+ //! Top-k is built by sorting the backend's `(id, score)` output
12
+ //! descending by score (tiebreak ascending by id) and truncating. The
13
+ //! flat backend returns every label-matching entity; future ANN
14
+ //! backends can return at most `k` and still satisfy the same
15
+ //! contract.
14
16
 
15
17
  use std::any::Any;
16
- use std::collections::BTreeMap;
18
+ use std::collections::{BTreeMap, BTreeSet};
17
19
 
18
20
  use anyhow::{anyhow, Result};
19
21
  use lora_ast::{Expr, ProcedureInvocationKind, StandaloneCall, YieldItem};
20
22
  use lora_executor::{LoraValue, Row};
21
23
  use lora_store::{
22
- cosine_similarity_bounded, euclidean_similarity, GraphStorage, GraphStorageMut,
23
- IndexDefinition, LoraVector, PropertyValue, StoredIndexEntity, StoredIndexKind,
24
+ GraphStorage, GraphStorageMut, IndexDefinition, LoraVector, StoredIndexEntity, StoredIndexKind,
24
25
  VectorCoordinateType,
25
26
  };
26
27
 
@@ -71,23 +72,25 @@ where
71
72
  params: &BTreeMap<String, LoraValue>,
72
73
  entity: StoredIndexEntity,
73
74
  ) -> Result<Vec<Row>> {
74
- let (index_name, k, query_vec) = parse_vector_args(args, params)?;
75
+ let (index_name, k, query_vec, restrict_to) = parse_vector_args(args, params)?;
75
76
  let snapshot = self.read_store();
76
77
  let def = snapshot
77
78
  .get_index(&index_name)
78
79
  .ok_or_else(|| anyhow!("no vector index named `{index_name}`"))?;
79
80
 
80
81
  validate_procedure_index(&def, StoredIndexKind::Vector, entity, "vector")?;
81
- let label = def
82
- .label
83
- .as_deref()
84
- .ok_or_else(|| anyhow!("vector index `{index_name}` has no label/type"))?;
85
- let property = def
86
- .properties
87
- .first()
88
- .ok_or_else(|| anyhow!("vector index `{index_name}` has no property column"))?;
82
+ // Catalog sanity: the schema validator guarantees both fields
83
+ // exist, so any miss here is a corrupted catalog row, not user
84
+ // input.
85
+ if def.label.is_none() {
86
+ return Err(anyhow!("vector index `{index_name}` has no label/type"));
87
+ }
88
+ if def.properties.is_empty() {
89
+ return Err(anyhow!(
90
+ "vector index `{index_name}` has no property column"
91
+ ));
92
+ }
89
93
 
90
- let similarity = similarity_from_definition(&def)?;
91
94
  let expected_dim = expected_dimension(&def);
92
95
  if let Some(dim) = expected_dim {
93
96
  if query_vec.dimension != dim {
@@ -99,7 +102,7 @@ where
99
102
  }
100
103
  }
101
104
 
102
- let scored = score_entities(&*snapshot, entity, label, property, &query_vec, similarity);
105
+ let scored = snapshot.vector_search(&index_name, &query_vec, k, restrict_to.as_ref());
103
106
  Ok(scored_rows(scored, Some(k), entity))
104
107
  }
105
108
 
@@ -157,35 +160,6 @@ enum ProcedureKind {
157
160
  Fulltext,
158
161
  }
159
162
 
160
- #[derive(Clone, Copy)]
161
- enum Similarity {
162
- Cosine,
163
- Euclidean,
164
- }
165
-
166
- fn similarity_from_definition(def: &IndexDefinition) -> Result<Similarity> {
167
- let sim = def
168
- .options
169
- .get("vector.similarity_function")
170
- .and_then(|v| match v {
171
- lora_store::IndexConfigValue::String(s) => Some(s.as_str()),
172
- _ => None,
173
- })
174
- .ok_or_else(|| {
175
- anyhow!(
176
- "vector index `{}` is missing `vector.similarity_function`",
177
- def.name
178
- )
179
- })?;
180
- if sim.eq_ignore_ascii_case("cosine") {
181
- Ok(Similarity::Cosine)
182
- } else if sim.eq_ignore_ascii_case("euclidean") {
183
- Ok(Similarity::Euclidean)
184
- } else {
185
- Err(anyhow!("unknown similarity function `{sim}`"))
186
- }
187
- }
188
-
189
163
  fn expected_dimension(def: &IndexDefinition) -> Option<usize> {
190
164
  def.options.get("vector.dimensions").and_then(|v| match v {
191
165
  lora_store::IndexConfigValue::Integer(n) if *n > 0 => Some(*n as usize),
@@ -218,56 +192,6 @@ fn validate_procedure_index(
218
192
  Ok(())
219
193
  }
220
194
 
221
- fn score_entities<S: GraphStorage + ?Sized>(
222
- storage: &S,
223
- entity: StoredIndexEntity,
224
- label: &str,
225
- property: &str,
226
- query: &LoraVector,
227
- similarity: Similarity,
228
- ) -> Vec<(u64, f64)> {
229
- let mut scored: Vec<(u64, f64)> = Vec::new();
230
- match entity {
231
- StoredIndexEntity::Node => {
232
- for id in storage.node_ids_by_label(label) {
233
- let Some(record) = storage.node(id) else {
234
- continue;
235
- };
236
- let Some(PropertyValue::Vector(v)) = record.property(property) else {
237
- continue;
238
- };
239
- if let Some(score) = score_pair(v, query, similarity) {
240
- scored.push((id, score));
241
- }
242
- }
243
- }
244
- StoredIndexEntity::Relationship => {
245
- for id in storage.rel_ids_by_type(label) {
246
- let Some(record) = storage.relationship(id) else {
247
- continue;
248
- };
249
- let Some(PropertyValue::Vector(v)) = record.property(property) else {
250
- continue;
251
- };
252
- if let Some(score) = score_pair(v, query, similarity) {
253
- scored.push((id, score));
254
- }
255
- }
256
- }
257
- }
258
- scored
259
- }
260
-
261
- fn score_pair(a: &LoraVector, b: &LoraVector, similarity: Similarity) -> Option<f64> {
262
- if a.dimension != b.dimension {
263
- return None;
264
- }
265
- match similarity {
266
- Similarity::Cosine => cosine_similarity_bounded(a, b),
267
- Similarity::Euclidean => euclidean_similarity(a, b),
268
- }
269
- }
270
-
271
195
  fn scored_rows(
272
196
  mut scored: Vec<(u64, f64)>,
273
197
  limit: Option<usize>,
@@ -325,10 +249,10 @@ fn parse_fulltext_args(
325
249
  fn parse_vector_args(
326
250
  args: &[Expr],
327
251
  params: &BTreeMap<String, LoraValue>,
328
- ) -> Result<(String, usize, LoraVector)> {
329
- if args.len() != 3 {
252
+ ) -> Result<(String, usize, LoraVector, Option<BTreeSet<u64>>)> {
253
+ if args.len() < 3 || args.len() > 4 {
330
254
  return Err(anyhow!(
331
- "vector procedure expects 3 arguments (indexName, k, query); got {}",
255
+ "vector procedure expects 3 or 4 arguments (indexName, k, query, options?); got {}",
332
256
  args.len()
333
257
  ));
334
258
  }
@@ -338,7 +262,81 @@ fn parse_vector_args(
338
262
  return Err(anyhow!("k must be positive"));
339
263
  }
340
264
  let query = eval_vector_arg(&args[2], params)?;
341
- Ok((name, k, query))
265
+ let restrict_to = if args.len() == 4 {
266
+ parse_vector_options(&args[3], params)?
267
+ } else {
268
+ None
269
+ };
270
+ Ok((name, k, query, restrict_to))
271
+ }
272
+
273
+ /// Parse the optional 4th-argument options map. Currently the only
274
+ /// honored key is `restrictTo`, a list of entity ids that limits
275
+ /// returned results. Unknown keys are rejected so users notice
276
+ /// typos at call time rather than silently getting unfiltered
277
+ /// behaviour.
278
+ fn parse_vector_options(
279
+ expr: &Expr,
280
+ params: &BTreeMap<String, LoraValue>,
281
+ ) -> Result<Option<BTreeSet<u64>>> {
282
+ let entries = match expr {
283
+ Expr::Map(items, _) => items.clone(),
284
+ // A $param map binding lands as LoraValue::Map after
285
+ // resolution; we don't currently take that path because
286
+ // resolve_literal would need a Map arm. For now, require an
287
+ // inline map literal in the procedure call.
288
+ other => {
289
+ return Err(anyhow!(
290
+ "vector procedure options must be a MAP literal like {{restrictTo: [...]}}, got {other:?}"
291
+ ));
292
+ }
293
+ };
294
+ let mut restrict_to: Option<BTreeSet<u64>> = None;
295
+ for (key, value) in entries {
296
+ match key.as_str() {
297
+ "restrictTo" => {
298
+ let resolved = resolve_literal(&value, params)?;
299
+ restrict_to = Some(coerce_id_set(&resolved)?);
300
+ }
301
+ other => {
302
+ return Err(anyhow!(
303
+ "unknown option `{other}` for db.index.vector.queryNodes (known: `restrictTo`)"
304
+ ));
305
+ }
306
+ }
307
+ }
308
+ Ok(restrict_to)
309
+ }
310
+
311
+ fn coerce_id_set(value: &LoraValue) -> Result<BTreeSet<u64>> {
312
+ let items = match value {
313
+ LoraValue::List(xs) => xs,
314
+ other => {
315
+ return Err(anyhow!(
316
+ "`restrictTo` must be a LIST of node ids, got {other:?}"
317
+ ));
318
+ }
319
+ };
320
+ let mut out = BTreeSet::new();
321
+ for item in items {
322
+ match item {
323
+ LoraValue::Int(n) if *n >= 0 => {
324
+ out.insert(*n as u64);
325
+ }
326
+ LoraValue::Node(id) => {
327
+ out.insert(*id);
328
+ }
329
+ LoraValue::Relationship(id) => {
330
+ out.insert(*id);
331
+ }
332
+ other => {
333
+ return Err(anyhow!(
334
+ "`restrictTo` entries must be non-negative integers or node/relationship references, got {other:?}"
335
+ ));
336
+ }
337
+ }
338
+ }
339
+ Ok(out)
342
340
  }
343
341
 
344
342
  fn eval_string_arg(