From f0d22976c74611d35b270ba90bbea0892c3dc758 Mon Sep 17 00:00:00 2001 From: Hassan Abedi Date: Fri, 10 Apr 2026 16:07:26 +0200 Subject: [PATCH] WIP --- src/execution/table_store.rs | 72 ++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/execution/table_store.rs diff --git a/src/execution/table_store.rs b/src/execution/table_store.rs new file mode 100644 index 0000000..33711e7 --- /dev/null +++ b/src/execution/table_store.rs @@ -0,0 +1,72 @@ +//! An in-memory table store backed by hash maps. + +use std::collections::HashMap; + +use crate::relational::{ResultSet, Row, Schema}; + +use super::{DataSource, ExecutionError}; + +/// A simple in-memory data source backed by named tables of rows. +/// +/// Unlike [`Instance`](crate::chase::Instance), which stores chase-level atoms, +/// `TableStore` holds typed relational rows directly. This makes it useful for +/// testing and for scenarios where data does not originate from the chase engine. +#[derive(Debug, Clone, Default)] +pub struct TableStore { + tables: HashMap)>, +} + +impl TableStore { + /// Create an empty table store. + pub fn new() -> Self { + Self::default() + } + + /// Register a table with its schema and initial rows. + pub fn insert(&mut self, name: impl Into, schema: Schema, rows: Vec) { + self.tables.insert(name.into(), (schema, rows)); + } +} + +impl DataSource for TableStore { + fn scan(&self, table: &str, schema: &Schema) -> Result { + match self.tables.get(table) { + Some((_, rows)) => Ok(ResultSet::new(schema.clone(), rows.clone())), + None => Ok(ResultSet::new(schema.clone(), Vec::new())), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::relational::{DataType, Field, Value}; + + #[test] + fn scans_registered_table() { + let schema = Schema::new(vec![ + Field::new("name", DataType::Text, false), + Field::new("age", DataType::Integer, false), + ]); + + let rows = vec![ + Row::new(vec![Value::text("alice"), Value::Integer(30)]), + Row::new(vec![Value::text("bob"), Value::Integer(25)]), + ]; + + let mut store = TableStore::new(); + store.insert("people", schema.clone(), rows); + + let result = store.scan("people", &schema).unwrap(); + assert_eq!(result.rows().len(), 2); + assert_eq!(result.schema().fields()[0].name(), "name"); + } + + #[test] + fn returns_empty_for_missing_table() { + let store = TableStore::new(); + let schema = Schema::new(vec![]); + let result = store.scan("missing", &schema).unwrap(); + assert_eq!(result.rows().len(), 0); + } +}