This commit is contained in:
Hassan Abedi 2026-06-05 13:06:06 +02:00
parent 07dab90bd6
commit 751ef2e47e
14 changed files with 28 additions and 20 deletions

View File

@ -129,7 +129,7 @@ fn row_count(storage: &GeomergeStorage, table: &str) -> Result<usize, StorageErr
#[allow(clippy::expect_used, clippy::unwrap_used)] #[allow(clippy::expect_used, clippy::unwrap_used)]
mod tests { mod tests {
use super::{ use super::{
add_paths_data, load_paths_theory, row_count, run_demo, GeomergeStorage, Storage, Value, GeomergeStorage, Storage, Value, add_paths_data, load_paths_theory, row_count, run_demo,
}; };
#[test] #[test]

View File

@ -29,6 +29,14 @@ The exporter (`tools/exporter`) is the only producer of runner IR today;
it's where atoms are planned and rejected if they don't fit the supported subset. it's where atoms are planned and rejected if they don't fit the supported subset.
Fixtures are regenerated with `make export-fixtures`, and the full loop is `make examples`. Fixtures are regenerated with `make export-fixtures`, and the full loop is `make examples`.
What happens inside the runner once a JSON plan arrives:
<div align="center">
<picture>
<img alt="Workflow" src="docs/diagrams/workflow.svg" height="90%" width="90%">
</picture>
</div>
### Backends ### Backends
The CLI takes a `--backend` flag. The CLI takes a `--backend` flag.

View File

@ -35,12 +35,12 @@ use std::collections::HashMap;
use serde::Deserialize; use serde::Deserialize;
use query_ops::atom::{scan_atom, AtomPattern, Term}; use query_ops::atom::{AtomPattern, Term, scan_atom};
use query_ops::join::{natural_join, semijoin}; use query_ops::join::{natural_join, semijoin};
use query_ops::relation::Relation; use query_ops::relation::Relation;
use storage::table::Table; use storage::table::Table;
use storage::value::Value; use storage::value::Value;
use storage::{scan_as_table, Storage, StorageError}; use storage::{Storage, StorageError, scan_as_table};
/// A single fixture: schema, ground facts, and a query plan to execute. /// A single fixture: schema, ground facts, and a query plan to execute.
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]

View File

@ -19,7 +19,8 @@ use std::collections::HashMap;
use std::io::{self, Read}; use std::io::{self, Read};
use std::process::ExitCode; use std::process::ExitCode;
use plan_runner::{build_tables, build_tables_via_storage, execute, parse_plan, JsonValue, Plan}; use plan_runner::{JsonValue, Plan, build_tables, build_tables_via_storage, execute, parse_plan};
use storage::MemoryStorage;
use storage::adapters::fjall::FjallStorage; use storage::adapters::fjall::FjallStorage;
use storage::adapters::geomerge::{ColumnKind, GeomergeStorage}; use storage::adapters::geomerge::{ColumnKind, GeomergeStorage};
use storage::adapters::lmdb::LmdbStorage; use storage::adapters::lmdb::LmdbStorage;
@ -27,7 +28,6 @@ use storage::adapters::redb::RedbStorage;
use storage::adapters::sqlite::SqliteStorage; use storage::adapters::sqlite::SqliteStorage;
use storage::table::Table; use storage::table::Table;
use storage::value::Value; use storage::value::Value;
use storage::MemoryStorage;
use tempfile::TempDir; use tempfile::TempDir;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]

View File

@ -8,8 +8,8 @@
//! with a different `S`. //! with a different `S`.
use plan_runner::{build_tables, build_tables_via_storage, execute, parse_plan, run_json}; use plan_runner::{build_tables, build_tables_via_storage, execute, parse_plan, run_json};
use storage::value::Value;
use storage::MemoryStorage; use storage::MemoryStorage;
use storage::value::Value;
const FIXTURE: &str = include_str!("../fixtures/three_atom_chain.json"); const FIXTURE: &str = include_str!("../fixtures/three_atom_chain.json");

View File

@ -13,7 +13,7 @@
//! bestsellers via a semijoin against `bestseller`, then attaches each book's //! bestsellers via a semijoin against `bestseller`, then attaches each book's
//! price via a natural join against `price`. //! price via a natural join against `price`.
use query_ops::atom::{scan_atom, AtomPattern, Term}; use query_ops::atom::{AtomPattern, Term, scan_atom};
use query_ops::join::{natural_join, semijoin}; use query_ops::join::{natural_join, semijoin};
use storage::table::Table; use storage::table::Table;
use storage::value::Value; use storage::value::Value;

View File

@ -4,10 +4,10 @@
//! Demonstrates that `query-ops` operators can consume from a storage backend //! Demonstrates that `query-ops` operators can consume from a storage backend
//! through the [`scan_as_table`] bridge, with no changes to `query-ops` itself. //! through the [`scan_as_table`] bridge, with no changes to `query-ops` itself.
use query_ops::atom::{scan_atom, AtomPattern, Term}; use query_ops::atom::{AtomPattern, Term, scan_atom};
use storage::table::Table; use storage::table::Table;
use storage::value::Value; use storage::value::Value;
use storage::{scan_as_table, MemoryStorage, Storage, StorageError}; use storage::{MemoryStorage, Storage, StorageError, scan_as_table};
fn i(x: i64) -> Value { fn i(x: i64) -> Value {
Value::Int(x) Value::Int(x)

View File

@ -18,7 +18,7 @@
#![allow(clippy::unwrap_used, clippy::expect_used)] #![allow(clippy::unwrap_used, clippy::expect_used)]
use criterion::{black_box, criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; use criterion::{BatchSize, BenchmarkId, Criterion, black_box, criterion_group, criterion_main};
use storage::value::Value; use storage::value::Value;
use storage::{MemoryStorage, Storage}; use storage::{MemoryStorage, Storage};

View File

@ -19,7 +19,7 @@
#![allow(clippy::unwrap_used, clippy::expect_used)] #![allow(clippy::unwrap_used, clippy::expect_used)]
use criterion::{black_box, criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; use criterion::{BatchSize, BenchmarkId, Criterion, black_box, criterion_group, criterion_main};
use geomerge::ir::FlatTheory; use geomerge::ir::FlatTheory;
use storage::adapters::geomerge::GeomergeStorage; use storage::adapters::geomerge::GeomergeStorage;
use storage::id::RowId; use storage::id::RowId;

View File

@ -16,7 +16,7 @@ use fjall::{Keyspace, PartitionCreateOptions, PartitionHandle};
use crate::codec::{decode_meta, decode_row, encode_meta, encode_row}; use crate::codec::{decode_meta, decode_row, encode_meta, encode_row};
use crate::id::RowId; use crate::id::RowId;
use crate::value::Value; use crate::value::Value;
use crate::{backend, CommittedTx, RowStream, Storage, StorageError, Transaction}; use crate::{CommittedTx, RowStream, Storage, StorageError, Transaction, backend};
const META_PARTITION: &str = "__meta"; const META_PARTITION: &str = "__meta";
@ -176,7 +176,7 @@ impl Transaction for FjallTx<'_> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{backend, FjallStorage}; use super::{FjallStorage, backend};
use crate::value::Value; use crate::value::Value;
use crate::{Storage, StorageError}; use crate::{Storage, StorageError};

View File

@ -43,7 +43,7 @@ use geomerge::txn::ops::{RowRef, TempRowId, TxnCellValue};
use crate::id::RowId; use crate::id::RowId;
use crate::value::Value; use crate::value::Value;
use crate::{backend, CommittedTx, RowStream, Storage, StorageError, Transaction}; use crate::{CommittedTx, RowStream, Storage, StorageError, Transaction, backend};
const GM_ROW_ID_LEN: usize = 32 + 4; const GM_ROW_ID_LEN: usize = 32 + 4;
const PENDING_ROW_ID_LEN: usize = 4; const PENDING_ROW_ID_LEN: usize = 4;

View File

@ -16,7 +16,7 @@ use heed::{Database, Env, EnvOpenOptions, RwTxn};
use crate::codec::{decode_meta, decode_row, encode_meta, encode_row, row_key}; use crate::codec::{decode_meta, decode_row, encode_meta, encode_row, row_key};
use crate::id::RowId; use crate::id::RowId;
use crate::value::Value; use crate::value::Value;
use crate::{backend, CommittedTx, RowStream, Storage, StorageError, Transaction}; use crate::{CommittedTx, RowStream, Storage, StorageError, Transaction, backend};
const META_DB: &str = "__meta"; const META_DB: &str = "__meta";
const DEFAULT_MAX_DBS: u32 = 128; const DEFAULT_MAX_DBS: u32 = 128;
@ -245,7 +245,7 @@ impl Transaction for LmdbTx<'_> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{backend, LmdbStorage}; use super::{LmdbStorage, backend};
use crate::value::Value; use crate::value::Value;
use crate::{Storage, StorageError}; use crate::{Storage, StorageError};

View File

@ -15,7 +15,7 @@ use redb::{Database, ReadableTable, TableDefinition, WriteTransaction};
use crate::codec::{decode_meta, decode_row, encode_meta, encode_row}; use crate::codec::{decode_meta, decode_row, encode_meta, encode_row};
use crate::id::RowId; use crate::id::RowId;
use crate::value::Value; use crate::value::Value;
use crate::{backend, CommittedTx, RowStream, Storage, StorageError, Transaction}; use crate::{CommittedTx, RowStream, Storage, StorageError, Transaction, backend};
const META_TABLE: &str = "__meta"; const META_TABLE: &str = "__meta";
@ -199,7 +199,7 @@ impl Transaction for RedbTx {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{backend, RedbStorage}; use super::{RedbStorage, backend};
use crate::value::Value; use crate::value::Value;
use crate::{Storage, StorageError}; use crate::{Storage, StorageError};

View File

@ -14,12 +14,12 @@
use std::collections::HashMap; use std::collections::HashMap;
use rusqlite::{params, Connection, OptionalExtension}; use rusqlite::{Connection, OptionalExtension, params};
use crate::codec::{decode_row, encode_row}; use crate::codec::{decode_row, encode_row};
use crate::id::RowId; use crate::id::RowId;
use crate::value::Value; use crate::value::Value;
use crate::{backend, CommittedTx, RowStream, Storage, StorageError, Transaction}; use crate::{CommittedTx, RowStream, Storage, StorageError, Transaction, backend};
const SCHEMA_SQL: &str = " const SCHEMA_SQL: &str = "
CREATE TABLE IF NOT EXISTS __meta ( CREATE TABLE IF NOT EXISTS __meta (