kimberlite-query 0.5.0

SQL query layer for Kimberlite projections
Documentation

kmb-query: SQL query layer for Kimberlite projections

This crate provides a minimal SQL query engine for compliance lookups against the projection store.

SQL Subset

Supported SQL features:

  • SELECT with column list or *
  • FROM single table or JOIN (INNER, LEFT, RIGHT, FULL OUTER, CROSS, with ON or USING(...) clauses)
  • WHERE with comparison predicates (=, <, >, <=, >=, IN)
  • IN (SELECT ...), EXISTS, NOT EXISTS (uncorrelated subqueries)
  • ORDER BY (ascending/descending)
  • LIMIT and OFFSET — literal or $N parameter
  • GROUP BY with aggregates (COUNT, SUM, AVG, MIN, MAX)
  • Aggregate FILTER (WHERE ...) clauses, independent per aggregate
  • HAVING with aggregate filtering
  • UNION / UNION ALL / INTERSECT / INTERSECT ALL / EXCEPT / EXCEPT ALL
  • DISTINCT
  • JSON operators ->, ->>, @> in WHERE clauses
  • CASE (searched and simple form)
  • WITH (Common Table Expressions / CTEs), including WITH RECURSIVE via iterative fixed-point evaluation (depth cap 1000)
  • Subqueries in FROM and JOIN (SELECT * FROM (SELECT ...) AS t)
  • Window functions (OVER, PARTITION BY, ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, FIRST_VALUE, LAST_VALUE)
  • ALTER TABLE (ADD COLUMN, DROP COLUMN) — parser only; kernel execution pending
  • Parameterized queries ($1, $2, ...) in WHERE, LIMIT, OFFSET, and DML values

Not yet supported:

  • Correlated subqueries (uncorrelated only above)
  • Scalar function projections (UPPER, ROUND, EXTRACT, ...) in SELECT
  • ILIKE, NOT LIKE, NOT ILIKE
  • COALESCE, NULLIF, CAST in WHERE expressions

Usage

use kimberlite_query::{QueryEngine, Schema, SchemaBuilder, ColumnDef, DataType, Value};
use kimberlite_store::{BTreeStore, TableId};

// Define schema
let schema = SchemaBuilder::new()
    .table(
        "users",
        TableId::new(1),
        vec![
            ColumnDef::new("id", DataType::BigInt).not_null(),
            ColumnDef::new("name", DataType::Text).not_null(),
        ],
        vec!["id".into()],
    )
    .build();

// Create engine
let engine = QueryEngine::new(schema);

// Execute query
let mut store = BTreeStore::open("data/projections")?;
let result = engine.query(&mut store, "SELECT * FROM users WHERE id = $1", &[Value::BigInt(42)])?;

Point-in-Time Queries

For compliance, you can query at a specific log position:

let result = engine.query_at(
    &mut store,
    "SELECT * FROM users WHERE id = 1",
    &[],
    Offset::new(1000),  // Query state as of log position 1000
)?;