@lix-js/sdk 0.6.0-preview.3 → 0.6.0-preview.5

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 (235) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +105 -65
  3. package/dist/engine-wasm/index.js +4 -4
  4. package/dist/engine-wasm/wasm/lix_engine.d.ts +30 -6
  5. package/dist/engine-wasm/wasm/lix_engine.js +187 -117
  6. package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
  7. package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +14 -8
  8. package/dist/generated/builtin-schemas.d.ts +69 -69
  9. package/dist/generated/builtin-schemas.js +94 -94
  10. package/dist/open-lix.d.ts +42 -28
  11. package/dist/open-lix.js +49 -10
  12. package/dist/sqlite/index.js +86 -30
  13. package/dist-engine-src/README.md +3 -3
  14. package/dist-engine-src/src/backend/capabilities.rs +67 -0
  15. package/dist-engine-src/src/backend/conformance/baseline.rs +1127 -0
  16. package/dist-engine-src/src/backend/conformance/factory.rs +93 -0
  17. package/dist-engine-src/src/backend/conformance/failure_tests.rs +608 -0
  18. package/dist-engine-src/src/backend/conformance/fixtures.rs +26 -0
  19. package/dist-engine-src/src/backend/conformance/mod.rs +75 -0
  20. package/dist-engine-src/src/backend/conformance/model.rs +28 -0
  21. package/dist-engine-src/src/backend/conformance/model_based.rs +257 -0
  22. package/dist-engine-src/src/backend/conformance/persistence.rs +204 -0
  23. package/dist-engine-src/src/backend/conformance/projection.rs +21 -0
  24. package/dist-engine-src/src/backend/conformance/pushdown.rs +24 -0
  25. package/dist-engine-src/src/backend/conformance/runner.rs +90 -0
  26. package/dist-engine-src/src/backend/conformance/scan.rs +24 -0
  27. package/dist-engine-src/src/backend/conformance/write.rs +16 -0
  28. package/dist-engine-src/src/backend/error.rs +94 -0
  29. package/dist-engine-src/src/backend/in_memory.rs +670 -0
  30. package/dist-engine-src/src/backend/mod.rs +36 -9
  31. package/dist-engine-src/src/backend/predicate.rs +80 -0
  32. package/dist-engine-src/src/backend/traits.rs +260 -0
  33. package/dist-engine-src/src/backend/types.rs +224 -81
  34. package/dist-engine-src/src/binary_cas/context.rs +8 -8
  35. package/dist-engine-src/src/binary_cas/kv.rs +234 -259
  36. package/dist-engine-src/src/{version → branch}/context.rs +12 -12
  37. package/dist-engine-src/src/branch/lifecycle.rs +221 -0
  38. package/dist-engine-src/src/branch/mod.rs +13 -0
  39. package/dist-engine-src/src/branch/refs.rs +321 -0
  40. package/dist-engine-src/src/branch/stage_rows.rs +67 -0
  41. package/dist-engine-src/src/branch/types.rs +21 -0
  42. package/dist-engine-src/src/catalog/context.rs +18 -18
  43. package/dist-engine-src/src/catalog/snapshot.rs +8 -8
  44. package/dist-engine-src/src/changelog/bench_support.rs +785 -0
  45. package/dist-engine-src/src/changelog/change.rs +1 -0
  46. package/dist-engine-src/src/changelog/codec.rs +497 -0
  47. package/dist-engine-src/src/changelog/commit.rs +1 -0
  48. package/dist-engine-src/src/changelog/context.rs +1614 -0
  49. package/dist-engine-src/src/changelog/mod.rs +29 -0
  50. package/dist-engine-src/src/changelog/store.rs +163 -0
  51. package/dist-engine-src/src/changelog/test_support.rs +54 -0
  52. package/dist-engine-src/src/changelog/types.rs +213 -0
  53. package/dist-engine-src/src/commit_graph/context.rs +317 -274
  54. package/dist-engine-src/src/commit_graph/mod.rs +2 -4
  55. package/dist-engine-src/src/commit_graph/types.rs +22 -42
  56. package/dist-engine-src/src/commit_graph/walker.rs +133 -103
  57. package/dist-engine-src/src/common/error.rs +52 -18
  58. package/dist-engine-src/src/common/identity.rs +2 -2
  59. package/dist-engine-src/src/common/mod.rs +1 -1
  60. package/dist-engine-src/src/domain.rs +42 -46
  61. package/dist-engine-src/src/engine.rs +74 -96
  62. package/dist-engine-src/src/{entity_identity.rs → entity_pk.rs} +89 -92
  63. package/dist-engine-src/src/functions/context.rs +56 -52
  64. package/dist-engine-src/src/functions/state.rs +51 -52
  65. package/dist-engine-src/src/init.rs +288 -154
  66. package/dist-engine-src/src/json_store/context.rs +15 -266
  67. package/dist-engine-src/src/json_store/mod.rs +26 -0
  68. package/dist-engine-src/src/json_store/store.rs +103 -718
  69. package/dist-engine-src/src/json_store/types.rs +4 -9
  70. package/dist-engine-src/src/lib.rs +49 -19
  71. package/dist-engine-src/src/live_state/context.rs +654 -790
  72. package/dist-engine-src/src/live_state/mod.rs +9 -3
  73. package/dist-engine-src/src/live_state/overlay.rs +4 -4
  74. package/dist-engine-src/src/live_state/types.rs +30 -21
  75. package/dist-engine-src/src/live_state/visibility.rs +514 -71
  76. package/dist-engine-src/src/plugin/install.rs +48 -48
  77. package/dist-engine-src/src/plugin/manifest.rs +7 -7
  78. package/dist-engine-src/src/plugin/materializer.rs +0 -275
  79. package/dist-engine-src/src/plugin/plugin_manifest.json +4 -3
  80. package/dist-engine-src/src/schema/builtin/lix_binary_blob_ref.json +2 -2
  81. package/dist-engine-src/src/schema/builtin/lix_branch_descriptor.json +34 -0
  82. package/dist-engine-src/src/schema/builtin/lix_branch_ref.json +48 -0
  83. package/dist-engine-src/src/schema/builtin/lix_change.json +3 -3
  84. package/dist-engine-src/src/schema/builtin/lix_commit.json +1 -1
  85. package/dist-engine-src/src/schema/builtin/lix_label_assignment.json +6 -6
  86. package/dist-engine-src/src/schema/builtin/mod.rs +18 -20
  87. package/dist-engine-src/src/schema/compatibility.rs +11 -11
  88. package/dist-engine-src/src/schema/definition.json +2 -2
  89. package/dist-engine-src/src/schema/definition.rs +5 -5
  90. package/dist-engine-src/src/schema/key.rs +3 -3
  91. package/dist-engine-src/src/schema/mod.rs +1 -1
  92. package/dist-engine-src/src/schema/tests.rs +18 -18
  93. package/dist-engine-src/src/session/context.rs +819 -124
  94. package/dist-engine-src/src/session/create_branch.rs +94 -0
  95. package/dist-engine-src/src/session/execute.rs +260 -57
  96. package/dist-engine-src/src/session/merge/analysis.rs +9 -3
  97. package/dist-engine-src/src/session/merge/{version.rs → branch.rs} +119 -129
  98. package/dist-engine-src/src/session/merge/conflicts.rs +2 -2
  99. package/dist-engine-src/src/session/merge/mod.rs +5 -6
  100. package/dist-engine-src/src/session/merge/stats.rs +7 -11
  101. package/dist-engine-src/src/session/mod.rs +19 -16
  102. package/dist-engine-src/src/session/switch_branch.rs +113 -0
  103. package/dist-engine-src/src/session/transaction.rs +557 -0
  104. package/dist-engine-src/src/sql2/bind/classify.rs +102 -0
  105. package/dist-engine-src/src/sql2/bind/error.rs +5 -0
  106. package/dist-engine-src/src/sql2/bind/expr.rs +29 -0
  107. package/dist-engine-src/src/sql2/bind/mod.rs +12 -0
  108. package/dist-engine-src/src/sql2/{udfs/public_call.rs → bind/public_udf.rs} +98 -3
  109. package/dist-engine-src/src/sql2/bind/read.rs +65 -0
  110. package/dist-engine-src/src/sql2/bind/statement.rs +2236 -0
  111. package/dist-engine-src/src/sql2/bind/table.rs +273 -0
  112. package/dist-engine-src/src/sql2/bind/write.rs +86 -0
  113. package/dist-engine-src/src/sql2/branch_scope.rs +436 -0
  114. package/dist-engine-src/src/sql2/catalog/capability.rs +20 -0
  115. package/dist-engine-src/src/sql2/catalog/entity_surface.rs +296 -0
  116. package/dist-engine-src/src/sql2/catalog/mod.rs +15 -0
  117. package/dist-engine-src/src/sql2/catalog/registry.rs +556 -0
  118. package/dist-engine-src/src/sql2/catalog/schema.rs +88 -0
  119. package/dist-engine-src/src/sql2/catalog/surface.rs +41 -0
  120. package/dist-engine-src/src/sql2/change_materialization.rs +122 -0
  121. package/dist-engine-src/src/sql2/context.rs +36 -30
  122. package/dist-engine-src/src/sql2/error.rs +4 -5
  123. package/dist-engine-src/src/sql2/exec/bound_public_write.rs +1593 -0
  124. package/dist-engine-src/src/sql2/exec/datafusion.rs +5266 -0
  125. package/dist-engine-src/src/sql2/exec/fast_write.rs +82 -0
  126. package/dist-engine-src/src/sql2/exec/mod.rs +24 -0
  127. package/dist-engine-src/src/sql2/exec/write.rs +661 -0
  128. package/dist-engine-src/src/sql2/filesystem_planner.rs +72 -77
  129. package/dist-engine-src/src/sql2/filesystem_visibility.rs +21 -21
  130. package/dist-engine-src/src/sql2/history_projection.rs +8 -8
  131. package/dist-engine-src/src/sql2/history_route.rs +35 -31
  132. package/dist-engine-src/src/sql2/mod.rs +30 -24
  133. package/dist-engine-src/src/sql2/optimize/datafusion.rs +1 -0
  134. package/dist-engine-src/src/sql2/optimize/mod.rs +2 -0
  135. package/dist-engine-src/src/sql2/optimize/simple_write.rs +116 -0
  136. package/dist-engine-src/src/sql2/parse/mod.rs +69 -0
  137. package/dist-engine-src/src/sql2/parse/normalize.rs +1 -0
  138. package/dist-engine-src/src/sql2/plan/branch_scope.rs +24 -0
  139. package/dist-engine-src/src/sql2/plan/mod.rs +5 -0
  140. package/dist-engine-src/src/sql2/plan/predicate.rs +22 -0
  141. package/dist-engine-src/src/sql2/plan/write.rs +147 -0
  142. package/dist-engine-src/src/sql2/predicate_typecheck.rs +258 -0
  143. package/dist-engine-src/src/sql2/{version_provider.rs → providers/branch.rs} +218 -214
  144. package/dist-engine-src/src/sql2/{change_provider.rs → providers/change.rs} +156 -42
  145. package/dist-engine-src/src/sql2/{directory_provider.rs → providers/directory.rs} +291 -322
  146. package/dist-engine-src/src/sql2/{directory_history_provider.rs → providers/directory_history.rs} +56 -42
  147. package/dist-engine-src/src/sql2/providers/entity.rs +1484 -0
  148. package/dist-engine-src/src/sql2/{entity_history_provider.rs → providers/entity_history.rs} +43 -31
  149. package/dist-engine-src/src/sql2/{file_provider.rs → providers/file.rs} +323 -316
  150. package/dist-engine-src/src/sql2/{file_history_provider.rs → providers/file_history.rs} +60 -46
  151. package/dist-engine-src/src/sql2/{history_provider.rs → providers/history.rs} +46 -32
  152. package/dist-engine-src/src/sql2/{lix_state_provider.rs → providers/lix_state.rs} +359 -329
  153. package/dist-engine-src/src/sql2/providers/mod.rs +508 -0
  154. package/dist-engine-src/src/sql2/read_only.rs +2 -2
  155. package/dist-engine-src/src/sql2/session.rs +47 -96
  156. package/dist-engine-src/src/sql2/storage/constraints.rs +1 -0
  157. package/dist-engine-src/src/sql2/storage/mod.rs +1 -0
  158. package/dist-engine-src/src/sql2/test_support/differential.rs +712 -0
  159. package/dist-engine-src/src/sql2/test_support/generators.rs +354 -0
  160. package/dist-engine-src/src/sql2/test_support/mod.rs +2 -0
  161. package/dist-engine-src/src/sql2/udfs/{lix_active_version_commit_id.rs → lix_active_branch_commit_id.rs} +7 -7
  162. package/dist-engine-src/src/sql2/udfs/mod.rs +3 -6
  163. package/dist-engine-src/src/sql2/write_normalization.rs +45 -22
  164. package/dist-engine-src/src/storage/conformance.rs +399 -0
  165. package/dist-engine-src/src/storage/context.rs +552 -288
  166. package/dist-engine-src/src/storage/mod.rs +48 -10
  167. package/dist-engine-src/src/storage/point.rs +440 -0
  168. package/dist-engine-src/src/storage/read_scope.rs +43 -64
  169. package/dist-engine-src/src/storage/reader.rs +867 -0
  170. package/dist-engine-src/src/storage/scan.rs +784 -0
  171. package/dist-engine-src/src/storage/spaces.rs +236 -0
  172. package/dist-engine-src/src/storage/stats.rs +80 -0
  173. package/dist-engine-src/src/storage/write_set.rs +962 -0
  174. package/dist-engine-src/src/storage_bench.rs +136 -4828
  175. package/dist-engine-src/src/test_support.rs +360 -138
  176. package/dist-engine-src/src/tracked_state/bench_support.rs +394 -0
  177. package/dist-engine-src/src/tracked_state/codec.rs +155 -1057
  178. package/dist-engine-src/src/tracked_state/commit_root_rebuild.rs +358 -0
  179. package/dist-engine-src/src/tracked_state/context.rs +1927 -993
  180. package/dist-engine-src/src/tracked_state/diff.rs +1715 -261
  181. package/dist-engine-src/src/tracked_state/merge.rs +74 -88
  182. package/dist-engine-src/src/tracked_state/mod.rs +19 -16
  183. package/dist-engine-src/src/tracked_state/{materialization.rs → row_materialization.rs} +50 -178
  184. package/dist-engine-src/src/tracked_state/storage.rs +243 -191
  185. package/dist-engine-src/src/tracked_state/tree.rs +247 -371
  186. package/dist-engine-src/src/tracked_state/types.rs +49 -42
  187. package/dist-engine-src/src/transaction/bench_support.rs +407 -0
  188. package/dist-engine-src/src/transaction/commit.rs +821 -713
  189. package/dist-engine-src/src/transaction/context.rs +705 -600
  190. package/dist-engine-src/src/transaction/mod.rs +13 -2
  191. package/dist-engine-src/src/transaction/normalization.rs +63 -76
  192. package/dist-engine-src/src/transaction/prep.rs +13 -13
  193. package/dist-engine-src/src/transaction/schema_resolver.rs +19 -5
  194. package/dist-engine-src/src/transaction/staging.rs +228 -434
  195. package/dist-engine-src/src/transaction/types.rs +41 -98
  196. package/dist-engine-src/src/transaction/validation.rs +382 -446
  197. package/dist-engine-src/src/untracked_state/codec.rs +337 -29
  198. package/dist-engine-src/src/untracked_state/context.rs +7 -7
  199. package/dist-engine-src/src/untracked_state/materialization.rs +2 -2
  200. package/dist-engine-src/src/untracked_state/mod.rs +1 -1
  201. package/dist-engine-src/src/untracked_state/storage.rs +659 -157
  202. package/dist-engine-src/src/untracked_state/types.rs +21 -21
  203. package/package.json +71 -68
  204. package/dist-engine-src/src/backend/kv.rs +0 -358
  205. package/dist-engine-src/src/backend/testing.rs +0 -658
  206. package/dist-engine-src/src/commit_store/codec.rs +0 -887
  207. package/dist-engine-src/src/commit_store/context.rs +0 -944
  208. package/dist-engine-src/src/commit_store/materialization.rs +0 -84
  209. package/dist-engine-src/src/commit_store/mod.rs +0 -16
  210. package/dist-engine-src/src/commit_store/storage.rs +0 -600
  211. package/dist-engine-src/src/commit_store/types.rs +0 -215
  212. package/dist-engine-src/src/schema/builtin/lix_version_descriptor.json +0 -34
  213. package/dist-engine-src/src/schema/builtin/lix_version_ref.json +0 -48
  214. package/dist-engine-src/src/session/create_version.rs +0 -88
  215. package/dist-engine-src/src/session/merge/apply.rs +0 -23
  216. package/dist-engine-src/src/session/optimization9_sql2_bench.rs +0 -100
  217. package/dist-engine-src/src/session/switch_version.rs +0 -109
  218. package/dist-engine-src/src/sql2/classify.rs +0 -182
  219. package/dist-engine-src/src/sql2/entity_provider.rs +0 -3211
  220. package/dist-engine-src/src/sql2/execute.rs +0 -3440
  221. package/dist-engine-src/src/sql2/public_bind/assignment.rs +0 -46
  222. package/dist-engine-src/src/sql2/public_bind/capability.rs +0 -41
  223. package/dist-engine-src/src/sql2/public_bind/dml.rs +0 -166
  224. package/dist-engine-src/src/sql2/public_bind/mod.rs +0 -25
  225. package/dist-engine-src/src/sql2/public_bind/table.rs +0 -168
  226. package/dist-engine-src/src/sql2/version_scope.rs +0 -394
  227. package/dist-engine-src/src/storage/types.rs +0 -501
  228. package/dist-engine-src/src/tracked_state/by_file_index.rs +0 -98
  229. package/dist-engine-src/src/tracked_state/materializer.rs +0 -488
  230. package/dist-engine-src/src/transaction/live_state_overlay.rs +0 -35
  231. package/dist-engine-src/src/version/lifecycle.rs +0 -221
  232. package/dist-engine-src/src/version/mod.rs +0 -13
  233. package/dist-engine-src/src/version/refs.rs +0 -330
  234. package/dist-engine-src/src/version/stage_rows.rs +0 -67
  235. package/dist-engine-src/src/version/types.rs +0 -21
@@ -7,7 +7,7 @@ use datafusion::arrow::compute::{and, filter_record_batch};
7
7
  use datafusion::arrow::datatypes::{DataType, Field, Schema, SchemaRef};
8
8
  use datafusion::arrow::record_batch::RecordBatch;
9
9
  use datafusion::catalog::{Session, TableProvider};
10
- use datafusion::common::{not_impl_err, DFSchema, DataFusionError, Result, ScalarValue};
10
+ use datafusion::common::{not_impl_err, DFSchema, DataFusionError, Result, ScalarValue, SchemaExt};
11
11
  use datafusion::datasource::TableType;
12
12
  use datafusion::execution::TaskContext;
13
13
  use datafusion::logical_expr::dml::InsertOp;
@@ -21,6 +21,10 @@ use datafusion::physical_plan::{
21
21
  use futures_util::{stream, TryStreamExt};
22
22
  use serde_json::Value as JsonValue;
23
23
 
24
+ use crate::branch::{
25
+ branch_descriptor_stage_row, branch_descriptor_tombstone_row, branch_ref_stage_row,
26
+ branch_ref_tombstone_row, BranchRefReader,
27
+ };
24
28
  use crate::live_state::{
25
29
  LiveStateFilter, LiveStateReader, LiveStateScanRequest, MaterializedLiveStateRow,
26
30
  };
@@ -28,83 +32,81 @@ use crate::sql2::dml::{InsertExec, InsertSink};
28
32
  use crate::sql2::record_batch::record_batch_with_row_count;
29
33
  use crate::sql2::write_normalization::{InsertCell, SqlCell, UpdateAssignmentValues};
30
34
  use crate::sql2::{
31
- SqlWriteContext, WriteAccess, WriteContextLiveStateReader, WriteContextVersionRefReader,
35
+ SqlWriteContext, WriteAccess, WriteContextBranchRefReader, WriteContextLiveStateReader,
32
36
  };
33
37
  use crate::transaction::types::{
34
38
  LogicalPrimaryKey, TransactionWrite, TransactionWriteMode, TransactionWriteOperation,
35
39
  TransactionWriteOrigin, TransactionWriteRow,
36
40
  };
37
- use crate::version::{
38
- version_descriptor_stage_row, version_descriptor_tombstone_row, version_ref_stage_row,
39
- version_ref_tombstone_row, VersionRefReader,
40
- };
41
41
  use crate::LixError;
42
- use crate::GLOBAL_VERSION_ID;
42
+ use crate::GLOBAL_BRANCH_ID;
43
43
 
44
- pub(crate) async fn register_lix_version_provider(
44
+ pub(super) async fn register_lix_branch_read_provider(
45
45
  session: &datafusion::prelude::SessionContext,
46
+ surface_name: &str,
46
47
  live_state: Arc<dyn LiveStateReader>,
47
- version_ref: Arc<dyn VersionRefReader>,
48
+ branch_ref: Arc<dyn BranchRefReader>,
48
49
  ) -> Result<(), LixError> {
49
50
  session
50
51
  .register_table(
51
- "lix_version",
52
- Arc::new(LixVersionProvider::new(live_state, version_ref)),
52
+ surface_name,
53
+ Arc::new(LixBranchProvider::new(live_state, branch_ref)),
53
54
  )
54
55
  .map_err(datafusion_error_to_lix_error)?;
55
56
  Ok(())
56
57
  }
57
58
 
58
- pub(crate) async fn register_lix_version_write_provider(
59
+ pub(super) async fn register_write_provider(
59
60
  session: &datafusion::prelude::SessionContext,
61
+ surface_name: &str,
60
62
  write_ctx: SqlWriteContext,
61
63
  ) -> Result<(), LixError> {
62
64
  session
63
65
  .register_table(
64
- "lix_version",
65
- Arc::new(LixVersionProvider::with_write(write_ctx)),
66
+ surface_name,
67
+ Arc::new(LixBranchProvider::with_write(write_ctx)),
66
68
  )
67
69
  .map_err(datafusion_error_to_lix_error)?;
68
70
  Ok(())
69
71
  }
70
72
 
71
- struct LixVersionProvider {
73
+ struct LixBranchProvider {
72
74
  schema: SchemaRef,
73
75
  live_state: Arc<dyn LiveStateReader>,
74
- version_ref: Arc<dyn VersionRefReader>,
76
+ branch_ref: Arc<dyn BranchRefReader>,
75
77
  write_access: WriteAccess,
76
78
  }
77
79
 
78
- impl std::fmt::Debug for LixVersionProvider {
80
+ impl std::fmt::Debug for LixBranchProvider {
79
81
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80
- f.debug_struct("LixVersionProvider").finish()
82
+ f.debug_struct("LixBranchProvider").finish()
81
83
  }
82
84
  }
83
85
 
84
- impl LixVersionProvider {
85
- fn new(live_state: Arc<dyn LiveStateReader>, version_ref: Arc<dyn VersionRefReader>) -> Self {
86
+ impl LixBranchProvider {
87
+ fn new(live_state: Arc<dyn LiveStateReader>, branch_ref: Arc<dyn BranchRefReader>) -> Self {
86
88
  Self {
87
- schema: lix_version_schema(),
89
+ schema: lix_branch_schema(),
88
90
  live_state,
89
- version_ref,
91
+ branch_ref,
90
92
  write_access: WriteAccess::read_only(),
91
93
  }
92
94
  }
93
95
 
94
96
  fn with_write(write_ctx: SqlWriteContext) -> Self {
95
97
  let live_state = Arc::new(WriteContextLiveStateReader::new(write_ctx.clone()));
96
- let version_ref = Arc::new(WriteContextVersionRefReader::new(write_ctx.clone()));
98
+ let branch_ref = Arc::new(WriteContextBranchRefReader::new(write_ctx.clone()));
97
99
  Self {
98
- schema: lix_version_schema(),
100
+ schema: lix_branch_schema(),
99
101
  live_state,
100
- version_ref,
102
+ branch_ref,
101
103
  write_access: WriteAccess::write(write_ctx),
102
104
  }
103
105
  }
104
106
  }
105
107
 
106
108
  #[async_trait]
107
- impl TableProvider for LixVersionProvider {
109
+ impl TableProvider for LixBranchProvider {
108
110
  fn as_any(&self) -> &dyn Any {
109
111
  self
110
112
  }
@@ -134,9 +136,9 @@ impl TableProvider for LixVersionProvider {
134
136
  _filters: &[Expr],
135
137
  _limit: Option<usize>,
136
138
  ) -> Result<Arc<dyn ExecutionPlan>> {
137
- Ok(Arc::new(LixVersionScanExec::new(
139
+ Ok(Arc::new(LixBranchScanExec::new(
138
140
  Arc::clone(&self.live_state),
139
- Arc::clone(&self.version_ref),
141
+ Arc::clone(&self.branch_ref),
140
142
  projected_schema(&self.schema, projection),
141
143
  projection.cloned(),
142
144
  )))
@@ -149,11 +151,12 @@ impl TableProvider for LixVersionProvider {
149
151
  insert_op: InsertOp,
150
152
  ) -> Result<Arc<dyn ExecutionPlan>> {
151
153
  if insert_op != InsertOp::Append {
152
- return not_impl_err!("{insert_op} not implemented for lix_version yet");
154
+ return not_impl_err!("{insert_op} not implemented for lix_branch yet");
153
155
  }
154
-
155
- let write_ctx = self.write_access.require_write("INSERT into lix_version")?;
156
- let sink = LixVersionInsertSink::new(input.schema(), write_ctx);
156
+ let write_ctx = self.write_access.require_write("INSERT into lix_branch")?;
157
+ self.schema
158
+ .logically_equivalent_names_and_types(&input.schema())?;
159
+ let sink = LixBranchInsertSink::new(write_ctx);
157
160
  Ok(Arc::new(InsertExec::new(input, Arc::new(sink))))
158
161
  }
159
162
 
@@ -162,17 +165,16 @@ impl TableProvider for LixVersionProvider {
162
165
  state: &dyn Session,
163
166
  filters: Vec<Expr>,
164
167
  ) -> Result<Arc<dyn ExecutionPlan>> {
165
- let write_ctx = self.write_access.require_write("DELETE FROM lix_version")?;
168
+ let write_ctx = self.write_access.require_write("DELETE FROM lix_branch")?;
166
169
  let df_schema = DFSchema::try_from(Arc::clone(&self.schema))?;
167
170
  let physical_filters = filters
168
171
  .iter()
169
172
  .map(|expr| create_physical_expr(expr, &df_schema, state.execution_props()))
170
173
  .collect::<Result<Vec<_>>>()?;
171
-
172
- Ok(Arc::new(LixVersionDeleteExec::new(
174
+ Ok(Arc::new(LixBranchDeleteExec::new(
173
175
  write_ctx,
174
176
  Arc::clone(&self.live_state),
175
- Arc::clone(&self.version_ref),
177
+ Arc::clone(&self.branch_ref),
176
178
  Arc::clone(&self.schema),
177
179
  physical_filters,
178
180
  )))
@@ -184,9 +186,8 @@ impl TableProvider for LixVersionProvider {
184
186
  assignments: Vec<(String, Expr)>,
185
187
  filters: Vec<Expr>,
186
188
  ) -> Result<Arc<dyn ExecutionPlan>> {
187
- let write_ctx = self.write_access.require_write("UPDATE lix_version")?;
188
- validate_lix_version_update_assignments(&assignments)?;
189
-
189
+ let write_ctx = self.write_access.require_write("UPDATE lix_branch")?;
190
+ validate_lix_branch_update_assignments(&assignments)?;
190
191
  let df_schema = DFSchema::try_from(Arc::clone(&self.schema))?;
191
192
  let physical_assignments = assignments
192
193
  .iter()
@@ -201,11 +202,10 @@ impl TableProvider for LixVersionProvider {
201
202
  .iter()
202
203
  .map(|expr| create_physical_expr(expr, &df_schema, state.execution_props()))
203
204
  .collect::<Result<Vec<_>>>()?;
204
-
205
- Ok(Arc::new(LixVersionUpdateExec::new(
205
+ Ok(Arc::new(LixBranchUpdateExec::new(
206
206
  write_ctx,
207
207
  Arc::clone(&self.live_state),
208
- Arc::clone(&self.version_ref),
208
+ Arc::clone(&self.branch_ref),
209
209
  Arc::clone(&self.schema),
210
210
  physical_assignments,
211
211
  physical_filters,
@@ -213,35 +213,35 @@ impl TableProvider for LixVersionProvider {
213
213
  }
214
214
  }
215
215
 
216
- struct LixVersionInsertSink {
216
+ struct LixBranchInsertSink {
217
217
  write_ctx: SqlWriteContext,
218
218
  }
219
219
 
220
- impl std::fmt::Debug for LixVersionInsertSink {
220
+ impl std::fmt::Debug for LixBranchInsertSink {
221
221
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
222
- f.debug_struct("LixVersionInsertSink").finish()
222
+ f.debug_struct("LixBranchInsertSink").finish()
223
223
  }
224
224
  }
225
225
 
226
- impl LixVersionInsertSink {
227
- fn new(_schema: SchemaRef, write_ctx: SqlWriteContext) -> Self {
226
+ impl LixBranchInsertSink {
227
+ fn new(write_ctx: SqlWriteContext) -> Self {
228
228
  Self { write_ctx }
229
229
  }
230
230
  }
231
231
 
232
- impl DisplayAs for LixVersionInsertSink {
232
+ impl DisplayAs for LixBranchInsertSink {
233
233
  fn fmt_as(&self, t: DisplayFormatType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
234
234
  match t {
235
235
  DisplayFormatType::Default | DisplayFormatType::Verbose => {
236
- write!(f, "LixVersionInsertSink")
236
+ write!(f, "LixBranchInsertSink")
237
237
  }
238
- DisplayFormatType::TreeRender => write!(f, "LixVersionInsertSink"),
238
+ DisplayFormatType::TreeRender => write!(f, "LixBranchInsertSink"),
239
239
  }
240
240
  }
241
241
  }
242
242
 
243
243
  #[async_trait]
244
- impl InsertSink for LixVersionInsertSink {
244
+ impl InsertSink for LixBranchInsertSink {
245
245
  async fn write_batches(
246
246
  &self,
247
247
  batches: Vec<RecordBatch>,
@@ -249,24 +249,24 @@ impl InsertSink for LixVersionInsertSink {
249
249
  ) -> Result<u64> {
250
250
  let default_commit_id = self
251
251
  .write_ctx
252
- .load_version_head(&self.write_ctx.active_version_id())
252
+ .load_branch_head(&self.write_ctx.active_branch_id())
253
253
  .await
254
254
  .map_err(lix_error_to_datafusion_error)?
255
255
  .ok_or_else(|| {
256
256
  DataFusionError::Execution(
257
- "INSERT into lix_version could not resolve active version head".to_string(),
257
+ "INSERT into lix_branch could not resolve active branch head".to_string(),
258
258
  )
259
259
  })?;
260
260
  let mut rows = Vec::new();
261
261
  let mut count = 0u64;
262
262
  for batch in batches {
263
- let version_rows = version_insert_rows_from_batch(&batch, &default_commit_id)?;
263
+ let branch_rows = branch_insert_rows_from_batch(&batch, &default_commit_id)?;
264
264
  count = count
265
- .checked_add(u64::try_from(version_rows.len()).map_err(|_| {
265
+ .checked_add(u64::try_from(branch_rows.len()).map_err(|_| {
266
266
  DataFusionError::Execution("INSERT row count overflow".to_string())
267
267
  })?)
268
268
  .ok_or_else(|| DataFusionError::Execution("INSERT row count overflow".into()))?;
269
- rows.extend(version_rows.into_iter().flat_map(version_insert_stage_rows));
269
+ rows.extend(branch_rows.into_iter().flat_map(branch_insert_stage_rows));
270
270
  }
271
271
 
272
272
  if !rows.is_empty() {
@@ -283,39 +283,39 @@ impl InsertSink for LixVersionInsertSink {
283
283
  }
284
284
  }
285
285
 
286
- struct LixVersionDeleteExec {
286
+ struct LixBranchDeleteExec {
287
287
  write_ctx: SqlWriteContext,
288
- active_version_id: String,
288
+ active_branch_id: String,
289
289
  live_state: Arc<dyn LiveStateReader>,
290
- version_ref: Arc<dyn VersionRefReader>,
290
+ branch_ref: Arc<dyn BranchRefReader>,
291
291
  table_schema: SchemaRef,
292
292
  filters: Vec<Arc<dyn PhysicalExpr>>,
293
293
  result_schema: SchemaRef,
294
294
  properties: Arc<PlanProperties>,
295
295
  }
296
296
 
297
- impl std::fmt::Debug for LixVersionDeleteExec {
297
+ impl std::fmt::Debug for LixBranchDeleteExec {
298
298
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
299
- f.debug_struct("LixVersionDeleteExec").finish()
299
+ f.debug_struct("LixBranchDeleteExec").finish()
300
300
  }
301
301
  }
302
302
 
303
- impl LixVersionDeleteExec {
303
+ impl LixBranchDeleteExec {
304
304
  fn new(
305
305
  write_ctx: SqlWriteContext,
306
306
  live_state: Arc<dyn LiveStateReader>,
307
- version_ref: Arc<dyn VersionRefReader>,
307
+ branch_ref: Arc<dyn BranchRefReader>,
308
308
  table_schema: SchemaRef,
309
309
  filters: Vec<Arc<dyn PhysicalExpr>>,
310
310
  ) -> Self {
311
311
  let result_schema = dml_count_schema();
312
312
  let properties = dml_plan_properties(Arc::clone(&result_schema));
313
- let active_version_id = write_ctx.active_version_id();
313
+ let active_branch_id = write_ctx.active_branch_id();
314
314
  Self {
315
315
  write_ctx,
316
- active_version_id,
316
+ active_branch_id,
317
317
  live_state,
318
- version_ref,
318
+ branch_ref,
319
319
  table_schema,
320
320
  filters,
321
321
  result_schema,
@@ -324,20 +324,20 @@ impl LixVersionDeleteExec {
324
324
  }
325
325
  }
326
326
 
327
- impl DisplayAs for LixVersionDeleteExec {
327
+ impl DisplayAs for LixBranchDeleteExec {
328
328
  fn fmt_as(&self, t: DisplayFormatType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
329
329
  match t {
330
330
  DisplayFormatType::Default | DisplayFormatType::Verbose => {
331
- write!(f, "LixVersionDeleteExec(filters={})", self.filters.len())
331
+ write!(f, "LixBranchDeleteExec(filters={})", self.filters.len())
332
332
  }
333
- DisplayFormatType::TreeRender => write!(f, "LixVersionDeleteExec"),
333
+ DisplayFormatType::TreeRender => write!(f, "LixBranchDeleteExec"),
334
334
  }
335
335
  }
336
336
  }
337
337
 
338
- impl ExecutionPlan for LixVersionDeleteExec {
338
+ impl ExecutionPlan for LixBranchDeleteExec {
339
339
  fn name(&self) -> &str {
340
- "LixVersionDeleteExec"
340
+ "LixBranchDeleteExec"
341
341
  }
342
342
 
343
343
  fn as_any(&self) -> &dyn Any {
@@ -358,7 +358,7 @@ impl ExecutionPlan for LixVersionDeleteExec {
358
358
  ) -> Result<Arc<dyn ExecutionPlan>> {
359
359
  if !children.is_empty() {
360
360
  return Err(DataFusionError::Execution(
361
- "LixVersionDeleteExec does not accept children".to_string(),
361
+ "LixBranchDeleteExec does not accept children".to_string(),
362
362
  ));
363
363
  }
364
364
  Ok(self)
@@ -371,31 +371,31 @@ impl ExecutionPlan for LixVersionDeleteExec {
371
371
  ) -> Result<SendableRecordBatchStream> {
372
372
  if partition != 0 {
373
373
  return Err(DataFusionError::Execution(format!(
374
- "LixVersionDeleteExec only exposes one partition, got {partition}"
374
+ "LixBranchDeleteExec only exposes one partition, got {partition}"
375
375
  )));
376
376
  }
377
377
  let write_ctx = self.write_ctx.clone();
378
- let active_version_id = self.active_version_id.clone();
378
+ let active_branch_id = self.active_branch_id.clone();
379
379
  let live_state = Arc::clone(&self.live_state);
380
- let version_ref = Arc::clone(&self.version_ref);
380
+ let branch_ref = Arc::clone(&self.branch_ref);
381
381
  let filters = self.filters.clone();
382
382
  let table_schema = Arc::clone(&self.table_schema);
383
383
  let result_schema = Arc::clone(&self.result_schema);
384
384
  let stream_schema = Arc::clone(&result_schema);
385
385
 
386
386
  let stream = stream::once(async move {
387
- let rows = load_version_rows(live_state, version_ref)
387
+ let rows = load_branch_rows(live_state, branch_ref)
388
388
  .await
389
389
  .map_err(lix_error_to_datafusion_error)?;
390
- let source_batch = version_record_batch(&version_projection_for_scan(None), &rows)?;
391
- let matched_batch = filter_version_batch(source_batch, &filters)?;
392
- let version_rows = version_rows_from_batch(&matched_batch)?;
393
- reject_protected_version_deletes(&version_rows, &active_version_id)?;
394
- let count = u64::try_from(version_rows.len())
390
+ let source_batch = branch_record_batch(&branch_projection_for_scan(None), &rows)?;
391
+ let matched_batch = filter_branch_batch(source_batch, &filters)?;
392
+ let branch_rows = branch_rows_from_batch(&matched_batch)?;
393
+ reject_protected_branch_deletes(&branch_rows, &active_branch_id)?;
394
+ let count = u64::try_from(branch_rows.len())
395
395
  .map_err(|_| DataFusionError::Execution("DELETE row count overflow".to_string()))?;
396
- let rows = version_rows
396
+ let rows = branch_rows
397
397
  .into_iter()
398
- .flat_map(version_tombstone_rows)
398
+ .flat_map(branch_tombstone_rows)
399
399
  .collect::<Vec<_>>();
400
400
 
401
401
  if !rows.is_empty() {
@@ -421,10 +421,10 @@ impl ExecutionPlan for LixVersionDeleteExec {
421
421
  }
422
422
  }
423
423
 
424
- struct LixVersionUpdateExec {
424
+ struct LixBranchUpdateExec {
425
425
  write_ctx: SqlWriteContext,
426
426
  live_state: Arc<dyn LiveStateReader>,
427
- version_ref: Arc<dyn VersionRefReader>,
427
+ branch_ref: Arc<dyn BranchRefReader>,
428
428
  table_schema: SchemaRef,
429
429
  assignments: Vec<(String, Arc<dyn PhysicalExpr>)>,
430
430
  filters: Vec<Arc<dyn PhysicalExpr>>,
@@ -432,17 +432,17 @@ struct LixVersionUpdateExec {
432
432
  properties: Arc<PlanProperties>,
433
433
  }
434
434
 
435
- impl std::fmt::Debug for LixVersionUpdateExec {
435
+ impl std::fmt::Debug for LixBranchUpdateExec {
436
436
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
437
- f.debug_struct("LixVersionUpdateExec").finish()
437
+ f.debug_struct("LixBranchUpdateExec").finish()
438
438
  }
439
439
  }
440
440
 
441
- impl LixVersionUpdateExec {
441
+ impl LixBranchUpdateExec {
442
442
  fn new(
443
443
  write_ctx: SqlWriteContext,
444
444
  live_state: Arc<dyn LiveStateReader>,
445
- version_ref: Arc<dyn VersionRefReader>,
445
+ branch_ref: Arc<dyn BranchRefReader>,
446
446
  table_schema: SchemaRef,
447
447
  assignments: Vec<(String, Arc<dyn PhysicalExpr>)>,
448
448
  filters: Vec<Arc<dyn PhysicalExpr>>,
@@ -452,7 +452,7 @@ impl LixVersionUpdateExec {
452
452
  Self {
453
453
  write_ctx,
454
454
  live_state,
455
- version_ref,
455
+ branch_ref,
456
456
  table_schema,
457
457
  assignments,
458
458
  filters,
@@ -462,25 +462,25 @@ impl LixVersionUpdateExec {
462
462
  }
463
463
  }
464
464
 
465
- impl DisplayAs for LixVersionUpdateExec {
465
+ impl DisplayAs for LixBranchUpdateExec {
466
466
  fn fmt_as(&self, t: DisplayFormatType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
467
467
  match t {
468
468
  DisplayFormatType::Default | DisplayFormatType::Verbose => {
469
469
  write!(
470
470
  f,
471
- "LixVersionUpdateExec(assignments={}, filters={})",
471
+ "LixBranchUpdateExec(assignments={}, filters={})",
472
472
  self.assignments.len(),
473
473
  self.filters.len()
474
474
  )
475
475
  }
476
- DisplayFormatType::TreeRender => write!(f, "LixVersionUpdateExec"),
476
+ DisplayFormatType::TreeRender => write!(f, "LixBranchUpdateExec"),
477
477
  }
478
478
  }
479
479
  }
480
480
 
481
- impl ExecutionPlan for LixVersionUpdateExec {
481
+ impl ExecutionPlan for LixBranchUpdateExec {
482
482
  fn name(&self) -> &str {
483
- "LixVersionUpdateExec"
483
+ "LixBranchUpdateExec"
484
484
  }
485
485
 
486
486
  fn as_any(&self) -> &dyn Any {
@@ -501,7 +501,7 @@ impl ExecutionPlan for LixVersionUpdateExec {
501
501
  ) -> Result<Arc<dyn ExecutionPlan>> {
502
502
  if !children.is_empty() {
503
503
  return Err(DataFusionError::Execution(
504
- "LixVersionUpdateExec does not accept children".to_string(),
504
+ "LixBranchUpdateExec does not accept children".to_string(),
505
505
  ));
506
506
  }
507
507
  Ok(self)
@@ -514,12 +514,12 @@ impl ExecutionPlan for LixVersionUpdateExec {
514
514
  ) -> Result<SendableRecordBatchStream> {
515
515
  if partition != 0 {
516
516
  return Err(DataFusionError::Execution(format!(
517
- "LixVersionUpdateExec only exposes one partition, got {partition}"
517
+ "LixBranchUpdateExec only exposes one partition, got {partition}"
518
518
  )));
519
519
  }
520
520
  let write_ctx = self.write_ctx.clone();
521
521
  let live_state = Arc::clone(&self.live_state);
522
- let version_ref = Arc::clone(&self.version_ref);
522
+ let branch_ref = Arc::clone(&self.branch_ref);
523
523
  let table_schema = Arc::clone(&self.table_schema);
524
524
  let assignments = self.assignments.clone();
525
525
  let filters = self.filters.clone();
@@ -527,18 +527,19 @@ impl ExecutionPlan for LixVersionUpdateExec {
527
527
  let stream_schema = Arc::clone(&result_schema);
528
528
 
529
529
  let stream = stream::once(async move {
530
- let rows = load_version_rows(live_state, version_ref)
530
+ let rows = load_branch_rows(live_state, branch_ref)
531
531
  .await
532
532
  .map_err(lix_error_to_datafusion_error)?;
533
- let source_batch = version_record_batch(&version_projection_for_scan(None), &rows)?;
534
- let matched_batch = filter_version_batch(source_batch, &filters)?;
535
- let version_rows =
536
- version_update_rows_from_batch(&matched_batch, &assignments, &table_schema)?;
537
- let count = u64::try_from(version_rows.len())
533
+ let source_batch = branch_record_batch(&branch_projection_for_scan(None), &rows)?;
534
+ let matched_batch = filter_branch_batch(source_batch, &filters)?;
535
+ let branch_rows =
536
+ branch_update_rows_from_batch(&matched_batch, &assignments, &table_schema)?;
537
+ reject_protected_branch_updates(&branch_rows)?;
538
+ let count = u64::try_from(branch_rows.len())
538
539
  .map_err(|_| DataFusionError::Execution("UPDATE row count overflow".to_string()))?;
539
- let rows = version_rows
540
+ let rows = branch_rows
540
541
  .into_iter()
541
- .flat_map(version_update_stage_rows)
542
+ .flat_map(branch_update_stage_rows)
542
543
  .collect::<Vec<_>>();
543
544
 
544
545
  if !rows.is_empty() {
@@ -563,24 +564,24 @@ impl ExecutionPlan for LixVersionUpdateExec {
563
564
  }
564
565
  }
565
566
 
566
- struct LixVersionScanExec {
567
+ struct LixBranchScanExec {
567
568
  live_state: Arc<dyn LiveStateReader>,
568
- version_ref: Arc<dyn VersionRefReader>,
569
+ branch_ref: Arc<dyn BranchRefReader>,
569
570
  schema: SchemaRef,
570
571
  projection: Option<Vec<usize>>,
571
572
  properties: Arc<PlanProperties>,
572
573
  }
573
574
 
574
- impl std::fmt::Debug for LixVersionScanExec {
575
+ impl std::fmt::Debug for LixBranchScanExec {
575
576
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
576
- f.debug_struct("LixVersionScanExec").finish()
577
+ f.debug_struct("LixBranchScanExec").finish()
577
578
  }
578
579
  }
579
580
 
580
- impl LixVersionScanExec {
581
+ impl LixBranchScanExec {
581
582
  fn new(
582
583
  live_state: Arc<dyn LiveStateReader>,
583
- version_ref: Arc<dyn VersionRefReader>,
584
+ branch_ref: Arc<dyn BranchRefReader>,
584
585
  schema: SchemaRef,
585
586
  projection: Option<Vec<usize>>,
586
587
  ) -> Self {
@@ -592,7 +593,7 @@ impl LixVersionScanExec {
592
593
  );
593
594
  Self {
594
595
  live_state,
595
- version_ref,
596
+ branch_ref,
596
597
  schema,
597
598
  projection,
598
599
  properties: Arc::new(properties),
@@ -600,20 +601,20 @@ impl LixVersionScanExec {
600
601
  }
601
602
  }
602
603
 
603
- impl DisplayAs for LixVersionScanExec {
604
+ impl DisplayAs for LixBranchScanExec {
604
605
  fn fmt_as(&self, t: DisplayFormatType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
605
606
  match t {
606
607
  DisplayFormatType::Default | DisplayFormatType::Verbose => {
607
- write!(f, "LixVersionScanExec")
608
+ write!(f, "LixBranchScanExec")
608
609
  }
609
- DisplayFormatType::TreeRender => write!(f, "LixVersionScanExec"),
610
+ DisplayFormatType::TreeRender => write!(f, "LixBranchScanExec"),
610
611
  }
611
612
  }
612
613
  }
613
614
 
614
- impl ExecutionPlan for LixVersionScanExec {
615
+ impl ExecutionPlan for LixBranchScanExec {
615
616
  fn name(&self) -> &str {
616
- "LixVersionScanExec"
617
+ "LixBranchScanExec"
617
618
  }
618
619
 
619
620
  fn as_any(&self) -> &dyn Any {
@@ -634,7 +635,7 @@ impl ExecutionPlan for LixVersionScanExec {
634
635
  ) -> Result<Arc<dyn ExecutionPlan>> {
635
636
  if !children.is_empty() {
636
637
  return Err(DataFusionError::Execution(
637
- "LixVersionScanExec does not accept children".to_string(),
638
+ "LixBranchScanExec does not accept children".to_string(),
638
639
  ));
639
640
  }
640
641
  Ok(self)
@@ -647,26 +648,26 @@ impl ExecutionPlan for LixVersionScanExec {
647
648
  ) -> Result<SendableRecordBatchStream> {
648
649
  if partition != 0 {
649
650
  return Err(DataFusionError::Execution(format!(
650
- "LixVersionScanExec only exposes one partition, got {partition}"
651
+ "LixBranchScanExec only exposes one partition, got {partition}"
651
652
  )));
652
653
  }
653
654
 
654
655
  let live_state = Arc::clone(&self.live_state);
655
- let version_ref = Arc::clone(&self.version_ref);
656
- let projection = version_projection_for_scan(self.projection.as_ref());
656
+ let branch_ref = Arc::clone(&self.branch_ref);
657
+ let projection = branch_projection_for_scan(self.projection.as_ref());
657
658
  let schema = Arc::clone(&self.schema);
658
659
  let stream = stream::once(async move {
659
- let rows = load_version_rows(live_state, version_ref)
660
+ let rows = load_branch_rows(live_state, branch_ref)
660
661
  .await
661
662
  .map_err(lix_error_to_datafusion_error)?;
662
- version_record_batch(&projection, &rows)
663
+ branch_record_batch(&projection, &rows)
663
664
  });
664
665
  Ok(Box::pin(RecordBatchStreamAdapter::new(schema, stream)))
665
666
  }
666
667
  }
667
668
 
668
669
  #[derive(Debug, Clone, PartialEq, Eq)]
669
- struct VersionRow {
670
+ struct BranchRow {
670
671
  id: String,
671
672
  name: String,
672
673
  hidden: bool,
@@ -674,22 +675,22 @@ struct VersionRow {
674
675
  }
675
676
 
676
677
  #[derive(Debug, Clone, Copy)]
677
- enum VersionColumn {
678
+ enum BranchColumn {
678
679
  Id,
679
680
  Name,
680
681
  Hidden,
681
682
  CommitId,
682
683
  }
683
684
 
684
- async fn load_version_rows(
685
+ async fn load_branch_rows(
685
686
  live_state: Arc<dyn LiveStateReader>,
686
- version_ref: Arc<dyn VersionRefReader>,
687
- ) -> Result<Vec<VersionRow>, LixError> {
687
+ branch_ref: Arc<dyn BranchRefReader>,
688
+ ) -> Result<Vec<BranchRow>, LixError> {
688
689
  let descriptor_rows = live_state
689
690
  .scan_rows(&LiveStateScanRequest {
690
691
  filter: LiveStateFilter {
691
- schema_keys: vec!["lix_version_descriptor".to_string()],
692
- version_ids: vec![GLOBAL_VERSION_ID.to_string()],
692
+ schema_keys: vec!["lix_branch_descriptor".to_string()],
693
+ branch_ids: vec![GLOBAL_BRANCH_ID.to_string()],
693
694
  ..LiveStateFilter::default()
694
695
  },
695
696
  projection: Default::default(),
@@ -700,10 +701,10 @@ async fn load_version_rows(
700
701
  let mut out = Vec::new();
701
702
  for descriptor_row in descriptor_rows {
702
703
  let descriptor = parse_descriptor(&descriptor_row)?;
703
- let Some(commit_id) = version_ref.load_head_commit_id(&descriptor.id).await? else {
704
+ let Some(commit_id) = branch_ref.load_head_commit_id(&descriptor.id).await? else {
704
705
  continue;
705
706
  };
706
- out.push(VersionRow {
707
+ out.push(BranchRow {
707
708
  commit_id,
708
709
  id: descriptor.id,
709
710
  name: descriptor.name,
@@ -714,34 +715,29 @@ async fn load_version_rows(
714
715
  }
715
716
 
716
717
  #[derive(Debug, Clone, PartialEq, Eq)]
717
- struct VersionDescriptor {
718
+ struct BranchDescriptor {
718
719
  id: String,
719
720
  name: String,
720
721
  hidden: bool,
721
722
  }
722
723
 
723
- fn parse_descriptor(row: &MaterializedLiveStateRow) -> Result<VersionDescriptor, LixError> {
724
- let snapshot = parse_snapshot(row, "lix_version_descriptor")?;
724
+ fn parse_descriptor(row: &MaterializedLiveStateRow) -> Result<BranchDescriptor, LixError> {
725
+ let snapshot = parse_snapshot(row, "lix_branch_descriptor")?;
725
726
  let id = snapshot
726
727
  .get("id")
727
728
  .and_then(JsonValue::as_str)
728
- .ok_or_else(|| LixError::new("LIX_ERROR_UNKNOWN", "lix_version_descriptor is missing id"))?
729
+ .ok_or_else(|| LixError::new("LIX_ERROR_UNKNOWN", "lix_branch_descriptor is missing id"))?
729
730
  .to_string();
730
731
  let name = snapshot
731
732
  .get("name")
732
733
  .and_then(JsonValue::as_str)
733
- .ok_or_else(|| {
734
- LixError::new(
735
- "LIX_ERROR_UNKNOWN",
736
- "lix_version_descriptor is missing name",
737
- )
738
- })?
734
+ .ok_or_else(|| LixError::new("LIX_ERROR_UNKNOWN", "lix_branch_descriptor is missing name"))?
739
735
  .to_string();
740
736
  let hidden = snapshot
741
737
  .get("hidden")
742
738
  .and_then(JsonValue::as_bool)
743
739
  .unwrap_or(false);
744
- Ok(VersionDescriptor { id, name, hidden })
740
+ Ok(BranchDescriptor { id, name, hidden })
745
741
  }
746
742
 
747
743
  fn parse_snapshot(row: &MaterializedLiveStateRow, schema_key: &str) -> Result<JsonValue, LixError> {
@@ -759,18 +755,18 @@ fn parse_snapshot(row: &MaterializedLiveStateRow, schema_key: &str) -> Result<Js
759
755
  })
760
756
  }
761
757
 
762
- fn validate_lix_version_update_assignments(assignments: &[(String, Expr)]) -> Result<()> {
758
+ fn validate_lix_branch_update_assignments(assignments: &[(String, Expr)]) -> Result<()> {
763
759
  for (column_name, _) in assignments {
764
760
  match column_name.as_str() {
765
761
  "name" | "hidden" | "commit_id" => {}
766
762
  "id" => {
767
763
  return Err(DataFusionError::Execution(
768
- "UPDATE lix_version cannot change immutable column 'id'".to_string(),
764
+ "UPDATE lix_branch cannot change immutable column 'id'".to_string(),
769
765
  ));
770
766
  }
771
767
  other => {
772
768
  return Err(DataFusionError::Plan(format!(
773
- "UPDATE lix_version failed: column '{other}' does not exist"
769
+ "UPDATE lix_branch failed: column '{other}' does not exist"
774
770
  )));
775
771
  }
776
772
  }
@@ -778,17 +774,17 @@ fn validate_lix_version_update_assignments(assignments: &[(String, Expr)]) -> Re
778
774
  Ok(())
779
775
  }
780
776
 
781
- fn filter_version_batch(
777
+ fn filter_branch_batch(
782
778
  batch: RecordBatch,
783
779
  filters: &[Arc<dyn PhysicalExpr>],
784
780
  ) -> Result<RecordBatch> {
785
- let Some(mask) = evaluate_version_filters(&batch, filters)? else {
781
+ let Some(mask) = evaluate_branch_filters(&batch, filters)? else {
786
782
  return Ok(batch);
787
783
  };
788
784
  Ok(filter_record_batch(&batch, &mask)?)
789
785
  }
790
786
 
791
- fn evaluate_version_filters(
787
+ fn evaluate_branch_filters(
792
788
  batch: &RecordBatch,
793
789
  filters: &[Arc<dyn PhysicalExpr>],
794
790
  ) -> Result<Option<BooleanArray>> {
@@ -804,7 +800,7 @@ fn evaluate_version_filters(
804
800
  .as_any()
805
801
  .downcast_ref::<BooleanArray>()
806
802
  .ok_or_else(|| {
807
- DataFusionError::Execution("lix_version filter was not boolean".to_string())
803
+ DataFusionError::Execution("lix_branch filter was not boolean".to_string())
808
804
  })?;
809
805
  let normalized = bool_array
810
806
  .iter()
@@ -818,10 +814,10 @@ fn evaluate_version_filters(
818
814
  Ok(combined_mask)
819
815
  }
820
816
 
821
- fn version_insert_rows_from_batch(
817
+ fn branch_insert_rows_from_batch(
822
818
  batch: &RecordBatch,
823
819
  default_commit_id: &str,
824
- ) -> Result<Vec<VersionRow>> {
820
+ ) -> Result<Vec<BranchRow>> {
825
821
  (0..batch.num_rows())
826
822
  .map(|row_index| {
827
823
  let id = required_string_value(batch, row_index, "id", "INSERT")?;
@@ -830,7 +826,7 @@ fn version_insert_rows_from_batch(
830
826
  optional_bool_value(batch, row_index, "hidden", "INSERT")?.unwrap_or(false);
831
827
  let commit_id = optional_string_value(batch, row_index, "commit_id", "INSERT")?
832
828
  .unwrap_or_else(|| default_commit_id.to_string());
833
- Ok(VersionRow {
829
+ Ok(BranchRow {
834
830
  id,
835
831
  name,
836
832
  hidden,
@@ -840,10 +836,10 @@ fn version_insert_rows_from_batch(
840
836
  .collect()
841
837
  }
842
838
 
843
- fn version_rows_from_batch(batch: &RecordBatch) -> Result<Vec<VersionRow>> {
839
+ fn branch_rows_from_batch(batch: &RecordBatch) -> Result<Vec<BranchRow>> {
844
840
  (0..batch.num_rows())
845
841
  .map(|row_index| {
846
- Ok(VersionRow {
842
+ Ok(BranchRow {
847
843
  id: required_string_value(batch, row_index, "id", "DELETE")?,
848
844
  name: required_string_value(batch, row_index, "name", "DELETE")?,
849
845
  hidden: required_bool_value(batch, row_index, "hidden", "DELETE")?,
@@ -853,16 +849,16 @@ fn version_rows_from_batch(batch: &RecordBatch) -> Result<Vec<VersionRow>> {
853
849
  .collect()
854
850
  }
855
851
 
856
- fn reject_protected_version_deletes(rows: &[VersionRow], active_version_id: &str) -> Result<()> {
852
+ fn reject_protected_branch_deletes(rows: &[BranchRow], active_branch_id: &str) -> Result<()> {
857
853
  for row in rows {
858
- if row.id == GLOBAL_VERSION_ID {
854
+ if row.id == GLOBAL_BRANCH_ID {
859
855
  return Err(DataFusionError::Execution(
860
- "DELETE FROM lix_version cannot delete the global version".to_string(),
856
+ "DELETE FROM lix_branch cannot delete the global branch".to_string(),
861
857
  ));
862
858
  }
863
- if row.id == active_version_id {
859
+ if row.id == active_branch_id {
864
860
  return Err(DataFusionError::Execution(format!(
865
- "DELETE FROM lix_version cannot delete active version '{}'",
861
+ "DELETE FROM lix_branch cannot delete active branch '{}'",
866
862
  row.id
867
863
  )));
868
864
  }
@@ -870,15 +866,26 @@ fn reject_protected_version_deletes(rows: &[VersionRow], active_version_id: &str
870
866
  Ok(())
871
867
  }
872
868
 
873
- fn version_update_rows_from_batch(
869
+ fn reject_protected_branch_updates(rows: &[BranchRow]) -> Result<()> {
870
+ for row in rows {
871
+ if row.id == GLOBAL_BRANCH_ID {
872
+ return Err(DataFusionError::Execution(
873
+ "UPDATE lix_branch cannot update the global branch".to_string(),
874
+ ));
875
+ }
876
+ }
877
+ Ok(())
878
+ }
879
+
880
+ fn branch_update_rows_from_batch(
874
881
  batch: &RecordBatch,
875
882
  assignments: &[(String, Arc<dyn PhysicalExpr>)],
876
883
  table_schema: &SchemaRef,
877
- ) -> Result<Vec<VersionRow>> {
884
+ ) -> Result<Vec<BranchRow>> {
878
885
  let assignment_values = UpdateAssignmentValues::evaluate(batch, assignments)?;
879
886
  (0..batch.num_rows())
880
887
  .map(|row_index| {
881
- Ok(VersionRow {
888
+ Ok(BranchRow {
882
889
  id: required_string_value(batch, row_index, "id", "UPDATE")?,
883
890
  name: update_string_value(
884
891
  batch,
@@ -906,38 +913,38 @@ fn version_update_rows_from_batch(
906
913
  .collect()
907
914
  }
908
915
 
909
- fn version_stage_rows(
910
- row: VersionRow,
916
+ fn branch_stage_rows(
917
+ row: BranchRow,
911
918
  origin: Option<TransactionWriteOrigin>,
912
919
  ) -> Vec<TransactionWriteRow> {
913
920
  vec![
914
921
  with_origin(
915
- version_descriptor_stage_row(&row.id, &row.name, row.hidden),
922
+ branch_descriptor_stage_row(&row.id, &row.name, row.hidden),
916
923
  origin.clone(),
917
924
  ),
918
- with_origin(version_ref_stage_row(&row.id, &row.commit_id), origin),
925
+ with_origin(branch_ref_stage_row(&row.id, &row.commit_id), origin),
919
926
  ]
920
927
  }
921
928
 
922
- fn version_tombstone_rows(row: VersionRow) -> Vec<TransactionWriteRow> {
923
- let origin = Some(lix_version_origin(
929
+ fn branch_tombstone_rows(row: BranchRow) -> Vec<TransactionWriteRow> {
930
+ let origin = Some(lix_branch_origin(
924
931
  TransactionWriteOperation::Delete,
925
932
  &row.id,
926
933
  ));
927
934
  vec![
928
- with_origin(version_descriptor_tombstone_row(&row.id), origin.clone()),
929
- with_origin(version_ref_tombstone_row(&row.id), origin),
935
+ with_origin(branch_descriptor_tombstone_row(&row.id), origin.clone()),
936
+ with_origin(branch_ref_tombstone_row(&row.id), origin),
930
937
  ]
931
938
  }
932
939
 
933
- fn version_insert_stage_rows(row: VersionRow) -> Vec<TransactionWriteRow> {
934
- let origin = lix_version_origin(TransactionWriteOperation::Insert, &row.id);
935
- version_stage_rows(row, Some(origin))
940
+ fn branch_insert_stage_rows(row: BranchRow) -> Vec<TransactionWriteRow> {
941
+ let origin = lix_branch_origin(TransactionWriteOperation::Insert, &row.id);
942
+ branch_stage_rows(row, Some(origin))
936
943
  }
937
944
 
938
- fn version_update_stage_rows(row: VersionRow) -> Vec<TransactionWriteRow> {
939
- let origin = lix_version_origin(TransactionWriteOperation::Update, &row.id);
940
- version_stage_rows(row, Some(origin))
945
+ fn branch_update_stage_rows(row: BranchRow) -> Vec<TransactionWriteRow> {
946
+ let origin = lix_branch_origin(TransactionWriteOperation::Update, &row.id);
947
+ branch_stage_rows(row, Some(origin))
941
948
  }
942
949
 
943
950
  fn with_origin(
@@ -948,16 +955,13 @@ fn with_origin(
948
955
  row
949
956
  }
950
957
 
951
- fn lix_version_origin(
952
- action: TransactionWriteOperation,
953
- version_id: &str,
954
- ) -> TransactionWriteOrigin {
958
+ fn lix_branch_origin(action: TransactionWriteOperation, branch_id: &str) -> TransactionWriteOrigin {
955
959
  TransactionWriteOrigin {
956
- surface: "lix_version".to_string(),
960
+ surface: "lix_branch".to_string(),
957
961
  operation: action,
958
962
  primary_key: Some(LogicalPrimaryKey {
959
963
  columns: vec!["id".to_string()],
960
- values: vec![version_id.to_string()],
964
+ values: vec![branch_id.to_string()],
961
965
  }),
962
966
  }
963
967
  }
@@ -978,16 +982,16 @@ fn update_string_value(
978
982
  | ScalarValue::LargeUtf8(Some(value)),
979
983
  )) => Ok(value),
980
984
  InsertCell::Provided(SqlCell::Null) => Err(DataFusionError::Execution(format!(
981
- "UPDATE lix_version requires non-null text column '{column_name}'"
985
+ "UPDATE lix_branch requires non-null text column '{column_name}'"
982
986
  ))),
983
987
  InsertCell::Provided(SqlCell::Value(other)) => Err(DataFusionError::Execution(format!(
984
- "UPDATE lix_version expected text-compatible column '{column_name}', got {other:?}"
988
+ "UPDATE lix_branch expected text-compatible column '{column_name}', got {other:?}"
985
989
  ))),
986
990
  }
987
991
  .or_else(|error| {
988
992
  if batch.column(column_index).is_null(row_index) {
989
993
  Err(DataFusionError::Execution(format!(
990
- "UPDATE lix_version requires non-null text column '{column_name}'"
994
+ "UPDATE lix_branch requires non-null text column '{column_name}'"
991
995
  )))
992
996
  } else {
993
997
  Err(error)
@@ -1007,16 +1011,16 @@ fn update_bool_value(
1007
1011
  InsertCell::Omitted => required_bool_value(batch, row_index, column_name, "UPDATE"),
1008
1012
  InsertCell::Provided(SqlCell::Value(ScalarValue::Boolean(Some(value)))) => Ok(value),
1009
1013
  InsertCell::Provided(SqlCell::Null) => Err(DataFusionError::Execution(format!(
1010
- "UPDATE lix_version requires non-null boolean column '{column_name}'"
1014
+ "UPDATE lix_branch requires non-null boolean column '{column_name}'"
1011
1015
  ))),
1012
1016
  InsertCell::Provided(SqlCell::Value(other)) => Err(DataFusionError::Execution(format!(
1013
- "UPDATE lix_version expected boolean column '{column_name}', got {other:?}"
1017
+ "UPDATE lix_branch expected boolean column '{column_name}', got {other:?}"
1014
1018
  ))),
1015
1019
  }
1016
1020
  .or_else(|error| {
1017
1021
  if batch.column(column_index).is_null(row_index) {
1018
1022
  Err(DataFusionError::Execution(format!(
1019
- "UPDATE lix_version requires non-null boolean column '{column_name}'"
1023
+ "UPDATE lix_branch requires non-null boolean column '{column_name}'"
1020
1024
  )))
1021
1025
  } else {
1022
1026
  Err(error)
@@ -1032,7 +1036,7 @@ fn required_string_value(
1032
1036
  ) -> Result<String> {
1033
1037
  optional_string_value(batch, row_index, column_name, action)?.ok_or_else(|| {
1034
1038
  DataFusionError::Execution(format!(
1035
- "{action} lix_version requires non-null text column '{column_name}'"
1039
+ "{action} lix_branch requires non-null text column '{column_name}'"
1036
1040
  ))
1037
1041
  })
1038
1042
  }
@@ -1053,7 +1057,7 @@ fn optional_string_value(
1053
1057
  | Some(ScalarValue::Utf8View(Some(value)))
1054
1058
  | Some(ScalarValue::LargeUtf8(Some(value))) => Ok(Some(value)),
1055
1059
  Some(other) => Err(DataFusionError::Execution(format!(
1056
- "{action} lix_version expected text-compatible column '{column_name}', got {other:?}"
1060
+ "{action} lix_branch expected text-compatible column '{column_name}', got {other:?}"
1057
1061
  ))),
1058
1062
  }
1059
1063
  }
@@ -1066,7 +1070,7 @@ fn required_bool_value(
1066
1070
  ) -> Result<bool> {
1067
1071
  optional_bool_value(batch, row_index, column_name, action)?.ok_or_else(|| {
1068
1072
  DataFusionError::Execution(format!(
1069
- "{action} lix_version requires non-null boolean column '{column_name}'"
1073
+ "{action} lix_branch requires non-null boolean column '{column_name}'"
1070
1074
  ))
1071
1075
  })
1072
1076
  }
@@ -1081,7 +1085,7 @@ fn optional_bool_value(
1081
1085
  None | Some(ScalarValue::Null) | Some(ScalarValue::Boolean(None)) => Ok(None),
1082
1086
  Some(ScalarValue::Boolean(Some(value))) => Ok(Some(value)),
1083
1087
  Some(other) => Err(DataFusionError::Execution(format!(
1084
- "{action} lix_version expected boolean column '{column_name}', got {other:?}"
1088
+ "{action} lix_branch expected boolean column '{column_name}', got {other:?}"
1085
1089
  ))),
1086
1090
  }
1087
1091
  }
@@ -1125,7 +1129,7 @@ fn dml_count_batch(schema: SchemaRef, count: u64) -> Result<RecordBatch> {
1125
1129
  .map_err(DataFusionError::from)
1126
1130
  }
1127
1131
 
1128
- fn lix_version_schema() -> SchemaRef {
1132
+ pub(super) fn lix_branch_schema() -> SchemaRef {
1129
1133
  Arc::new(Schema::new(vec![
1130
1134
  Field::new("id", DataType::Utf8, false),
1131
1135
  Field::new("name", DataType::Utf8, false),
@@ -1134,12 +1138,12 @@ fn lix_version_schema() -> SchemaRef {
1134
1138
  ]))
1135
1139
  }
1136
1140
 
1137
- fn version_projection_for_scan(projection: Option<&Vec<usize>>) -> Vec<VersionColumn> {
1141
+ fn branch_projection_for_scan(projection: Option<&Vec<usize>>) -> Vec<BranchColumn> {
1138
1142
  let all_columns = vec![
1139
- VersionColumn::Id,
1140
- VersionColumn::Name,
1141
- VersionColumn::Hidden,
1142
- VersionColumn::CommitId,
1143
+ BranchColumn::Id,
1144
+ BranchColumn::Name,
1145
+ BranchColumn::Hidden,
1146
+ BranchColumn::CommitId,
1143
1147
  ];
1144
1148
  projection.map_or(all_columns.clone(), |indices| {
1145
1149
  indices
@@ -1156,34 +1160,34 @@ fn projected_schema(schema: &SchemaRef, projection: Option<&Vec<usize>>) -> Sche
1156
1160
  }
1157
1161
  }
1158
1162
 
1159
- fn version_record_batch(projection: &[VersionColumn], rows: &[VersionRow]) -> Result<RecordBatch> {
1163
+ fn branch_record_batch(projection: &[BranchColumn], rows: &[BranchRow]) -> Result<RecordBatch> {
1160
1164
  let arrays = projection
1161
1165
  .iter()
1162
1166
  .map(|column| match column {
1163
- VersionColumn::Id => string_array(rows.iter().map(|row| Some(row.id.as_str()))),
1164
- VersionColumn::Name => string_array(rows.iter().map(|row| Some(row.name.as_str()))),
1165
- VersionColumn::Hidden => Arc::new(BooleanArray::from(
1167
+ BranchColumn::Id => string_array(rows.iter().map(|row| Some(row.id.as_str()))),
1168
+ BranchColumn::Name => string_array(rows.iter().map(|row| Some(row.name.as_str()))),
1169
+ BranchColumn::Hidden => Arc::new(BooleanArray::from(
1166
1170
  rows.iter().map(|row| row.hidden).collect::<Vec<_>>(),
1167
1171
  )) as ArrayRef,
1168
- VersionColumn::CommitId => {
1172
+ BranchColumn::CommitId => {
1169
1173
  string_array(rows.iter().map(|row| Some(row.commit_id.as_str())))
1170
1174
  }
1171
1175
  })
1172
1176
  .collect::<Vec<_>>();
1173
- record_batch_with_row_count(version_schema(projection), arrays, rows.len()).map_err(|error| {
1174
- DataFusionError::Execution(format!("failed to build lix_version batch: {error}"))
1177
+ record_batch_with_row_count(branch_schema(projection), arrays, rows.len()).map_err(|error| {
1178
+ DataFusionError::Execution(format!("failed to build lix_branch batch: {error}"))
1175
1179
  })
1176
1180
  }
1177
1181
 
1178
- fn version_schema(projection: &[VersionColumn]) -> SchemaRef {
1182
+ fn branch_schema(projection: &[BranchColumn]) -> SchemaRef {
1179
1183
  Arc::new(Schema::new(
1180
1184
  projection
1181
1185
  .iter()
1182
1186
  .map(|column| match column {
1183
- VersionColumn::Id => Field::new("id", DataType::Utf8, false),
1184
- VersionColumn::Name => Field::new("name", DataType::Utf8, false),
1185
- VersionColumn::Hidden => Field::new("hidden", DataType::Boolean, false),
1186
- VersionColumn::CommitId => Field::new("commit_id", DataType::Utf8, false),
1187
+ BranchColumn::Id => Field::new("id", DataType::Utf8, false),
1188
+ BranchColumn::Name => Field::new("name", DataType::Utf8, false),
1189
+ BranchColumn::Hidden => Field::new("hidden", DataType::Boolean, false),
1190
+ BranchColumn::CommitId => Field::new("commit_id", DataType::Utf8, false),
1187
1191
  })
1188
1192
  .collect::<Vec<_>>(),
1189
1193
  ))
@@ -1194,9 +1198,9 @@ fn string_array<'a>(values: impl Iterator<Item = Option<&'a str>>) -> ArrayRef {
1194
1198
  }
1195
1199
 
1196
1200
  fn datafusion_error_to_lix_error(error: DataFusionError) -> LixError {
1197
- super::error::datafusion_error_to_lix_error(error)
1201
+ crate::sql2::error::datafusion_error_to_lix_error(error)
1198
1202
  }
1199
1203
 
1200
1204
  fn lix_error_to_datafusion_error(error: LixError) -> DataFusionError {
1201
- super::error::lix_error_to_datafusion_error(error)
1205
+ crate::sql2::error::lix_error_to_datafusion_error(error)
1202
1206
  }