Skip to main content

QueryEngine

Struct QueryEngine 

Source
pub struct QueryEngine { /* private fields */ }
Expand description

Query engine for executing SQL against a projection store.

Holds the schema plus an optional parse cache (AUDIT-2026-04 S3.4). The engine is Clone — the parse cache is shared via Arc so cloned handles hit the same memoised entries.

Implementations§

Source§

impl QueryEngine

Source

pub fn new(schema: Schema) -> Self

Creates a new query engine with the given schema. No parse cache is attached by default — use Self::with_parse_cache to opt in.

Source

pub fn with_parse_cache(self, max_size: usize) -> Self

Attach an LRU parse cache of the given size. 0 disables caching (every call re-parses).

Source

pub fn with_correlated_cap(self, cap: u64) -> Self

Override the correlated-subquery row-evaluation cap. Defaults to 10,000,000. Queries whose estimated outer_rows × inner_rows_per_iter exceeds this cap fail with QueryError::CorrelatedCardinalityExceeded before the correlated loop runs. Set to u64::MAX to effectively disable.

Source

pub fn parse_cache_stats(&self) -> Option<ParseCacheStats>

Returns a snapshot of parse-cache stats, or None if no cache is attached.

Source

pub fn clear_parse_cache(&self)

Clear the parse cache, if any.

Source

pub fn schema(&self) -> &Schema

Returns a reference to the schema.

Source

pub fn query<S: ProjectionStore>( &self, store: &mut S, sql: &str, params: &[Value], ) -> Result<QueryResult>

Executes a SQL query against the current store state.

Supports SELECT and UNION/UNION ALL queries.

§Arguments
  • store - The projection store to query
  • sql - SQL query string
  • params - Query parameters (for $1, $2, etc.)
§Example
let result = engine.query(
    &mut store,
    "SELECT name FROM users WHERE id = $1",
    &[Value::BigInt(42)],
)?;
Source

pub fn query_at<S: ProjectionStore>( &self, store: &mut S, sql: &str, params: &[Value], position: Offset, ) -> Result<QueryResult>

Executes a SQL query at a specific log position (point-in-time query).

This enables compliance queries that show the state as it was at a specific point in the log.

§Arguments
  • store - The projection store to query
  • sql - SQL query string
  • params - Query parameters
  • position - Log position to query at
§Example
// Get user state as of log position 1000
let result = engine.query_at(
    &mut store,
    "SELECT * FROM users WHERE id = 1",
    &[],
    Offset::new(1000),
)?;
Source

pub fn query_at_timestamp<S, R>( &self, store: &mut S, sql: &str, params: &[Value], target_ns: i64, resolver: R, ) -> Result<QueryResult>

Executes a query against a historical snapshot selected by wall-clock timestamp (AUDIT-2026-04 L-4).

This is the user-facing ergonomic form of Self::query_at — healthcare auditors ask “what did the chart look like on 2026-01-15?”, not “what was log offset 948,274?”. The caller supplies a resolver callback that translates a Unix-nanosecond timestamp into the log offset whose commit timestamp is the greatest value ≤ the target.

The resolver is a callback rather than a hard dependency so the query crate does not take a direct dep on kimberlite-compliance::audit or the kernel’s audit log. A typical impl performs a binary search on the in-memory audit index.

§Errors
  • QueryError::UnsupportedFeature if the resolver returns None (no offset exists at or before the target — typically because the log is empty or the timestamp predates genesis).
§Example
let resolver = |ts_ns: i64| -> Option<Offset> {
    audit_log.offset_at_or_before(ts_ns)
};
let result = engine.query_at_timestamp(
    &mut store,
    "SELECT * FROM charts WHERE patient_id = $1",
    &[Value::BigInt(42)],
    1_760_000_000_000_000_000, // 2025-10-09T07:06:40Z in ns
    resolver,
)?;
Source

pub fn query_at_timestamp_resolved<S, R>( &self, store: &mut S, sql: &str, params: &[Value], target_ns: i64, resolver: R, ) -> Result<QueryResult>

Executes a query against a historical snapshot selected by wall-clock timestamp, with a resolver that can distinguish the “timestamp predates retention horizon” case from a plain “no offset found”.

v0.6.0 Tier 2 #6: this is the runtime-layer variant of Self::query_at_timestamp used by TenantHandle::query when the resolver has a concrete notion of a retention horizon (e.g. an in-memory timestamp index maintained at append time). The existing query_at_timestamp stays as-is so callers with an Option<Offset> resolver (e.g. ad-hoc binary search over an external index) keep working.

§Resolution semantics
Source

pub fn explain(&self, sql: &str, params: &[Value]) -> Result<String>

AUDIT-2026-04 S3.3 — render a SQL query’s access plan without executing it.

Returns a deterministic multi-line tree string — same query always produces the same bytes, which lets apps diff plans across schema versions and catch unexpected regressions.

The rendered plan never reveals row data — only table names, column counts, filter presence/absence, and LIMIT bounds. Masked column names render as their source name (masks are applied post-projection and are not a plan concern).

§Errors

Any error from parsing or planning (unsupported statement, missing table, etc.) propagates verbatim.

§Example
let tree = engine.explain("SELECT * FROM patients WHERE id = $1", &[Value::BigInt(42)])?;
println!("{tree}");
// -> PointLookup [patients, cols=3]
Source

pub fn prepare(&self, sql: &str, params: &[Value]) -> Result<PreparedQuery>

Parses a SQL query without executing it.

Useful for validation or query plan inspection.

Trait Implementations§

Source§

impl Clone for QueryEngine

Source§

fn clone(&self) -> QueryEngine

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for QueryEngine

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more