pub struct Engine { /* private fields */ }Implementations§
Source§impl Engine
impl Engine
pub fn execute_plan( &mut self, plan: &PlanNode, ) -> Result<QueryResult, QueryError>
Source§impl Engine
impl Engine
pub fn prepare(&mut self, query: &str) -> Result<PreparedQuery, QueryError>
Sourcepub fn execute_prepared(
&mut self,
prep: &PreparedQuery,
literals: &[Literal],
) -> Result<QueryResult, QueryError>
pub fn execute_prepared( &mut self, prep: &PreparedQuery, literals: &[Literal], ) -> Result<QueryResult, QueryError>
Execute a PreparedQuery with the given literal values.
The literals are substituted into a clone of the template plan in
the same deterministic walk order that crate::canonicalize
produces (filter predicate first, then projection, then assignment
RHS, and so on). Substitution errors here mean the caller passed
the wrong number of literals for this query shape.
Sourcepub fn execute_prepared_take(
&mut self,
prep: &PreparedQuery,
literals: &mut [Literal],
) -> Result<QueryResult, QueryError>
pub fn execute_prepared_take( &mut self, prep: &PreparedQuery, literals: &mut [Literal], ) -> Result<QueryResult, QueryError>
Mission C Phase 13: moving variant of Engine::execute_prepared
for the insert fast path. Takes literals by mutable reference
so that each Literal::String can be consumed via mem::take
instead of cloned into a Value::Str. On insert_batch_1k that
removes three per-row heap allocations (name, status, email),
bringing the workload over the line vs SQLite’s amortized
prepare+execute loop.
The caller’s Literal::String entries are replaced with empty
strings on successful inserts — the literals slice is not
left in a valid-for-reuse state except for Int/Float/Bool
values. Non-insert templates fall through to the standard
substitute-and-execute path.
Source§impl Engine
impl Engine
Sourcepub fn new(data_dir: &Path) -> Result<Self>
pub fn new(data_dir: &Path) -> Result<Self>
Open or create a PowDB engine rooted at data_dir.
If the directory already contains a catalog, it is reopened. Otherwise a fresh empty database is created.
§Examples
use powdb_query::executor::Engine;
let dir = tempfile::tempdir().unwrap();
let engine = Engine::new(dir.path()).unwrap();
// Engine is ready — the directory now contains a catalog.Sourcepub fn execute_powql(&mut self, input: &str) -> Result<QueryResult, QueryError>
pub fn execute_powql(&mut self, input: &str) -> Result<QueryResult, QueryError>
Parse + plan + execute a PowQL query.
§Examples
use powdb_query::executor::Engine;
use powdb_query::result::QueryResult;
let dir = tempfile::tempdir().unwrap();
let mut engine = Engine::new(dir.path()).unwrap();
// Create a table and insert a row.
engine.execute_powql("type User { required name: str, age: int }").unwrap();
engine.execute_powql(r#"insert User { name := "Alice", age := 30 }"#).unwrap();
// Query rows back.
let result = engine.execute_powql("User").unwrap();
assert_eq!(result.row_count(), 1);Mission D6 — tracing collapse: the previous implementation ran 4
Instant::now() + 3 elapsed().as_micros() calls + formatted an
info! span on every query, even when tracing was disabled. On a
sub-microsecond point_lookup_indexed call that overhead was
100-200ns — 20%+ of the whole query. We now measure time only when
INFO is actually enabled via tracing::enabled!, and we moved the
noisy debug!(?plan) line behind the same gate so the Debug
formatter can’t run unconditionally either.
Mission D9 — plan cache: on the hot path we canonicalise the query text (lex + FNV-1a hash with literal values stripped), check the cache, and on a hit substitute the new literals into a clone of the cached plan. This skips re-lexing, re-parsing, and re-planning — around 3μs per call on bench workloads. On a miss we plan as before and insert the plan under its canonical hash.
Sourcepub fn plan_cache_stats(&self) -> (u64, u64, usize)
pub fn plan_cache_stats(&self) -> (u64, u64, usize)
Plan cache stats — useful for benches and debugging.
Sourcepub fn execute_powql_readonly(
&self,
input: &str,
) -> Result<QueryResult, QueryError>
pub fn execute_powql_readonly( &self, input: &str, ) -> Result<QueryResult, QueryError>
Mission infra-1: read-only entry point.
Parses + plans + executes a PowQL query using only a shared borrow
on the engine. Rejects any statement that would mutate state
(Insert/Update/Delete/CreateTable/AlterTable/DropTable/CreateView/
RefreshView/DropView) by returning READONLY_NEEDS_WRITE so the
caller can escalate to the write lock.
Also returns READONLY_NEEDS_WRITE if a materialized view in the
query is dirty — refreshing one requires &mut self, so the caller
must retake the write lock for the first refresh.
This method is the concurrent-read fast path behind
Arc<RwLock<Engine>>: multiple threads can call it simultaneously
under a shared .read() lock and each will scan independently.