Expand description
§SiftQuery
A typed, parameter-driven, read-only query library for Rust and sqlx.
SiftQuery validates fields, operators, budgets, ordering and paging before executing parameterized SQL. Application authorization is supplied separately through ServerScope and GroupScope.
use sift_query::{PgSiftQuery, RawParams, SearchEntity, ServerScope};
#[derive(Debug, sqlx::FromRow, SearchEntity)]
#[search_entity(from = "app_user", stable_order = "id:asc")]
struct User {
#[search_field(sortable, cursor_non_null, operators = [Eq, InList])]
id: i64,
#[search_field(operators = [Eq, Contain])]
name: String,
}
let search = PgSiftQuery::new(pool);
let params = RawParams::parse("name=alice&name-op=ct&size=20")?;
let page = search.search::<User>(¶ms, &ServerScope::unrestricted()).await?;
assert!(page.data.len() <= 20);Features include nested conditions, typed queries, dynamic and static projections, summaries, signed cursors, bounded scan/CSV, codecs, named pools, web adapters, result enrichment and SQL template caching. PostgreSQL additionally exposes validate_schema::<E>() for EXPLAIN based startup/CI checks, ScopeProvider based authorized search entry points, and bounded server declared facets. Ordinary queries do not require a transaction. The cache stores SQL templates, never query results.
cursor_non_null is a server assertion for ordering expressions guaranteed non-null by the database (such as an unmodified primary key). It enables a range predicate without NULL branches; do not infer it solely from a Rust field type or use it on a nullable outer-join expression. Changing the assertion changes the schema fingerprint and invalidates old cursors.
PostgreSQL, MySQL/MariaDB and SQLite execution are separate backend crates. default-features = false provides the backend-independent model and derive macros. Enable exactly one of postgres, mysql or sqlite for execution; axum, actix-web and poem add PostgreSQL web integration. PostgreSQL-specific extensions remain optional, and a PostgreSQL installation does not acquire MySQL or SQLite drivers.
For MySQL/MariaDB use MySqlSiftQuery; for SQLite use SqliteSiftQuery. Both expose search, search_map, search_list, count, SearchOptions summaries, caller-owned connection/transaction entry points, bounded scan streams, CSV export, and the portable Web parameter adapters. PostgreSQL-only RLS, native types, full-text search, and extension features remain on the PostgreSQL backend.
Rust 1.99.0 or newer is required. The API is currently pre-1.0. Licensed under Apache-2.0.
Optional PostgreSQL search (postgres-search) example:
use sift_query::{postgres::{PgCapabilities, TextConfig}, *};
#[derive(Debug, sqlx::FromRow, SearchEntity)]
#[search_entity(from = "article", stable_order = "id:asc")]
struct Article {
#[search_field(sortable)]
id: i64,
#[sqlx(skip)]
#[search_field(column="document", kind=FilterOnly, selectable=false,
custom_operators=["fts_plain","fts_phrase","fts_web","fts_query"])]
document: FilterOnly<String>,
}
async fn search(pool: sqlx::PgPool) -> Result<(), Box<dyn std::error::Error>> {
let capabilities = PgCapabilities::default().with_full_text(TextConfig::English);
capabilities.check(&pool).await?; // explicit application initialization
let search = PgSiftQuery::with_policy(pool, capabilities.apply(QueryPolicy::default())?, PgExecutionPolicy::default())?;
let params = RawParams::parse("document=rust&document-op=fts_plain")?;
let _page = search.search::<Article>(¶ms, &ServerScope::unrestricted()).await?;
Ok(())
}Opt-in trusted RLS context (rls) keeps settings inside one transaction:
use sift_query::RlsConfig;
let config = RlsConfig::new(&["app.tenant"], &["app_reader"])?;
let context = config.context(&[("app.tenant", "trusted-tenant")], Some("app_reader"))?;
let transaction = search.begin_rls(&context, std::time::Duration::from_secs(5)).await?;
// Use transaction.search/search_map with application queries and ServerScope.
transaction.finish().await?;metadata exports safe query descriptions/OpenAPI fragments, rsql parses a bounded RSQL subset, postgres-types adds native array/range/network values, and pg-trgm/ltree/postgis enable optional extensions. These features are disabled by default.
Modules§
- core
- Backend-independent query model and strict parameter protocol for
SiftQuery. - postgres
- PostgreSQL bindings, result decoding and opt-in query capabilities.
- web
- PostgreSQL web adapter primitives shared by axum, actix-web, and poem.
Macros§
- search_
entities - Declares entities from reusable field fragments and named mapping presets.
Structs§
- Boolean
Codec - A strict pair of business boolean names (for example
enabled/disabled). - Bucket
Entry - Bucket
Result - Codec
Registry - A small, ordered collection of codecs.
- Condition
- Condition
Order - CsvColumn
- A server-owned export column and optional trusted formatter.
- CsvExport
Policy - CsvExporter
- Cursor
- Cursor
Codec - Cursor
Page - A cursor page fetched without a count or cluster query.
- Custom
Aggregate - Trusted server-side aggregate expression containing a
{field}placeholder. - Custom
Operator - Trusted server-side SQL template for a custom operator.
- Date
Codec - A configured date-only format. This codec has no implicit timezone;
use
TimestampCodecfor configured timezone conversion. - Date
Time Codec - Decode
Error - Default
Param Filter - Adds trusted default parameters before strict parsing.
- Diagnostic
Stage - Dictionary
Label Loader - Enum/local dictionaries share the same one-batch loader contract as remote services.
- Enrich
Context - Context passed to post-query, whole-page enrichers.
- Entity
Limits - Per-entity limits. Instance-level limits may only make these stricter.
- Entity
Meta - Static metadata generated for a search entity.
- Enum
Codec - Strict enum names mapped to an integer database field. Empty and unknown names/codes are errors; results use the same names accepted by input.
- Facet
Bucket - Facet
Page - A page plus server-declared facet buckets.
- Facet
Request - A server-declared facet over one entity field.
- Facet
Result - Facet
Result Set - Named result wrapper useful when facets are fetched independently.
- Field
Access Policy - Server-owned field visibility and queryability policy.
- Field
Access Policy Builder - Builder for an explicit least-privilege field policy.
- FieldId
- Stable, entity-local field identifier.
- Field
Meta - Metadata for one query-visible field.
- Field
Ref - Typed reference to one entity field.
- Filter
Expr - Entity-bound predicate expression for programmatic queries.
- Filter
Only - Marker stored in result structs for fields that participate only in filtering.
- Group
Scope - Service-controlled predicate evaluated after
GROUP BY. - Group
Scope Builder - Builder for service-owned aggregate predicates evaluated in HAVING.
- Index
Advice - A conservative, server-side index hint. It is advisory only and never creates or changes database indexes.
- Indexed
Array Param Filter - Converts repeated/indexed array keys to canonical indexed parameters.
- Json
Array Param Filter - Expands JSON arrays into indexed parameter values before strict parsing.
- Json
Value Codec - Label
- Label
Enricher - List
Result Codec - Literal separated database text -> typed presentation list. This does not add PostgreSQL array-column operators or change the database bind type.
- NodeId
- Numeric
Bucket Request - Operator
Set - A compact static operator whitelist.
- OrderBy
- Order
Meta - A validated static ordering item.
- Page
- Paging
- Param
Names - Names of protocol-level control parameters.
- Param
Parser - Strict parser from
RawParamsto an entity-bound query. - Partition
Name - PgExecution
Policy - PgPool
Router - Immutable server-owned entity-to-pool routing table.
- PgRenderer
- PgSift
Query - Predicate
Arena - Compact predicate storage with index-based edges.
- Projection
Field - Public
Error - Query
Builder - Programmatic builder for a validated
UserQuery. - Query
Context - Query
Diagnostic Report - Query
Hard Limits - Absolute library guardrails. Ordinary configuration cannot exceed these values.
- Query
Limits - Runtime query limits. Entity limits can only make paging values stricter.
- Query
Observation - Query
Params - Query
Plan - Immutable input to a backend renderer.
- Query
Policy - Immutable parser and execution policy.
- Query
Shape Cache - Bounded LRU cache for SQL templates and value-free bind instructions.
- Query
Shape Id - RawParams
- Decoded, ordered, multi-value query parameters.
- Registered
Operator - Rendered
PgQuery - Result
Context - Scalar
Text Codec - Configurable text representation for a scalar field. Parsing and result conversion use the same logical type, so cursor and database binds remain typed while the public text format is centralized in one codec.
- Scan
Policy - Server-owned single-statement scan budget. PostgreSQL provides one statement
snapshot;
batch_sizecontrols cooperative handoff, not cursor pagination. - Schema
Validation Error - Schema
Validation Report - Scope
Limits - Search
Options - Search
Param Config - Framework request configuration. Use the same limits as the query policy. Install as an axum extension, actix app data, or poem endpoint data.
- Search
Params - GET query / POST form parameters, preserving ordered repeated values.
- Server
Scope - Service-controlled row-level predicate.
- Server
Scope Builder - Server
SqlExtension - A server-owned SQL extension declaration. The SQL template remains in the binary and only bound values can come from a request.
- Server
SqlRegistry - Bounded registry used by an HTTP/service boundary. Registration is a startup operation; lookup accepts only a name that was registered by the server and never parses SQL supplied by a caller.
- Shape
Cache Stats - Cumulative observations for a bounded SQL-shape cache.
- SqlContext
- String
Codec - A strict text field codec with optional whitespace normalization. It is useful when an API’s representation must be explicit even though the underlying value is already a SQL text column.
- Suffix
Operator Param Filter - Rewrites operator suffixes to canonical parameters while preserving repeats.
- Summary
Request - Summary
Value - Time
Bucket Request - Time
Codec - Timestamp
Codec - Configured local format and IANA timezone, normalized to UTC for binding. Ambiguous and nonexistent local DST times are errors. RFC 3339 and epoch milliseconds are accepted as explicit instants, independent of local zone.
- Typed
List - A homogeneous array value used by PostgreSQL
ANY. - User
Query - WebError
- Safe default HTTP error adapter. Applications can override the mapping
using
public_errorwithout publishing the underlying database error.
Enums§
- Aggregate
Fn - Aggregate
Kind - Bucket
Request - Compatibility
Policy - Config
Error - Errors in static entity or policy configuration.
- Count
Strategy - Cursor
Value - Execution
Strategy - Extension
Error - Field
Kind - Determines whether a condition is evaluated before or after grouping.
- Filter
Only Kind - Group
KeyKind - Label
Failure Policy - Missing
Label Policy - Null
Order - Operator
- M1 field operators.
- Paging
Mode - Param
Error - Errors caused by untrusted query parameters or programmatic user queries.
- PgBind
Value - PgSearch
Error - Plan
Error - Errors while combining a validated user query with server policy.
- Pool
Route Error - Predicate
Node - Predicate
Phase - Projection
- Query
Target - Render
Error - Result
Filter Decision - RowValue
- Dynamic result value. Unlike
ScalarValue, this can represent SQL NULL. - Scalar
Kind - Scalar
Value - A typed, non-null scalar used in predicates.
- Schema
Validation Target - What the schema contract validator checked.
- Search
Error - Snapshot
Isolation - Sort
Order - Time
Bucket Unit - Timeout
Stage - Value
Type - Supported logical value types.
Traits§
- Codec
- A server-owned input/result conversion codec.
- Field
Convertor - Compatibility name for reflection-based field converters. Implementations
use the typed
Codeccontract and cannot bypass bind typing. - Into
Cursor Value - Into
Scalar Value - Label
Loader - Label
Target - Typed opt-in: implementations explicitly name the source fields and writable
label fields.
set_labelmust not modify database fields or ordering keys. - Page
Enricher - Asynchronous page-level result enhancement. Implementations should batch external lookups and must not change count, summaries, or cursor metadata.
- Partition
Resolver - PgPool
Selector - Application-owned, nonblocking resolver for trusted request context. Client query parameters are never supplied to this hook.
- PgSum
Type - PgSummary
Value - Query
Input - Query
Observer - Metrics/event bridge. Called once per completed or cancelled operation; panics are isolated. The callback must be nonblocking and cannot see SQL, binds, raw input, tenant identifiers, or cursor tokens.
- RawParam
Filter - A server-owned parameter normalization step.
- Result
Filter - RowPhase
Kind - Scope
Provider - Builds a server-owned authorization scope from a trusted request context.
- Search
Entity - Implemented by derive-generated query entities.
- Search
Projection - SqlInterceptor
- Summable
Kind - Typed
Page Enricher - Explicit typed opt-in: implementers declare which presentation fields may be filled and preserve database fields and ordering keys.