Skip to main content

Crate sift_query

Crate sift_query 

Source
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>(&params, &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>(&params, &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§

BooleanCodec
A strict pair of business boolean names (for example enabled/disabled).
BucketEntry
BucketResult
CodecRegistry
A small, ordered collection of codecs.
Condition
ConditionOrder
CsvColumn
A server-owned export column and optional trusted formatter.
CsvExportPolicy
CsvExporter
Cursor
CursorCodec
CursorPage
A cursor page fetched without a count or cluster query.
CustomAggregate
Trusted server-side aggregate expression containing a {field} placeholder.
CustomOperator
Trusted server-side SQL template for a custom operator.
DateCodec
A configured date-only format. This codec has no implicit timezone; use TimestampCodec for configured timezone conversion.
DateTimeCodec
DecodeError
DefaultParamFilter
Adds trusted default parameters before strict parsing.
DiagnosticStage
DictionaryLabelLoader
Enum/local dictionaries share the same one-batch loader contract as remote services.
EnrichContext
Context passed to post-query, whole-page enrichers.
EntityLimits
Per-entity limits. Instance-level limits may only make these stricter.
EntityMeta
Static metadata generated for a search entity.
EnumCodec
Strict enum names mapped to an integer database field. Empty and unknown names/codes are errors; results use the same names accepted by input.
FacetBucket
FacetPage
A page plus server-declared facet buckets.
FacetRequest
A server-declared facet over one entity field.
FacetResult
FacetResultSet
Named result wrapper useful when facets are fetched independently.
FieldAccessPolicy
Server-owned field visibility and queryability policy.
FieldAccessPolicyBuilder
Builder for an explicit least-privilege field policy.
FieldId
Stable, entity-local field identifier.
FieldMeta
Metadata for one query-visible field.
FieldRef
Typed reference to one entity field.
FilterExpr
Entity-bound predicate expression for programmatic queries.
FilterOnly
Marker stored in result structs for fields that participate only in filtering.
GroupScope
Service-controlled predicate evaluated after GROUP BY.
GroupScopeBuilder
Builder for service-owned aggregate predicates evaluated in HAVING.
IndexAdvice
A conservative, server-side index hint. It is advisory only and never creates or changes database indexes.
IndexedArrayParamFilter
Converts repeated/indexed array keys to canonical indexed parameters.
JsonArrayParamFilter
Expands JSON arrays into indexed parameter values before strict parsing.
JsonValueCodec
Label
LabelEnricher
ListResultCodec
Literal separated database text -> typed presentation list. This does not add PostgreSQL array-column operators or change the database bind type.
NodeId
NumericBucketRequest
OperatorSet
A compact static operator whitelist.
OrderBy
OrderMeta
A validated static ordering item.
Page
Paging
ParamNames
Names of protocol-level control parameters.
ParamParser
Strict parser from RawParams to an entity-bound query.
PartitionName
PgExecutionPolicy
PgPoolRouter
Immutable server-owned entity-to-pool routing table.
PgRenderer
PgSiftQuery
PredicateArena
Compact predicate storage with index-based edges.
ProjectionField
PublicError
QueryBuilder
Programmatic builder for a validated UserQuery.
QueryContext
QueryDiagnosticReport
QueryHardLimits
Absolute library guardrails. Ordinary configuration cannot exceed these values.
QueryLimits
Runtime query limits. Entity limits can only make paging values stricter.
QueryObservation
QueryParams
QueryPlan
Immutable input to a backend renderer.
QueryPolicy
Immutable parser and execution policy.
QueryShapeCache
Bounded LRU cache for SQL templates and value-free bind instructions.
QueryShapeId
RawParams
Decoded, ordered, multi-value query parameters.
RegisteredOperator
RenderedPgQuery
ResultContext
ScalarTextCodec
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.
ScanPolicy
Server-owned single-statement scan budget. PostgreSQL provides one statement snapshot; batch_size controls cooperative handoff, not cursor pagination.
SchemaValidationError
SchemaValidationReport
ScopeLimits
SearchOptions
SearchParamConfig
Framework request configuration. Use the same limits as the query policy. Install as an axum extension, actix app data, or poem endpoint data.
SearchParams
GET query / POST form parameters, preserving ordered repeated values.
ServerScope
Service-controlled row-level predicate.
ServerScopeBuilder
ServerSqlExtension
A server-owned SQL extension declaration. The SQL template remains in the binary and only bound values can come from a request.
ServerSqlRegistry
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.
ShapeCacheStats
Cumulative observations for a bounded SQL-shape cache.
SqlContext
StringCodec
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.
SuffixOperatorParamFilter
Rewrites operator suffixes to canonical parameters while preserving repeats.
SummaryRequest
SummaryValue
TimeBucketRequest
TimeCodec
TimestampCodec
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.
TypedList
A homogeneous array value used by PostgreSQL ANY.
UserQuery
WebError
Safe default HTTP error adapter. Applications can override the mapping using public_error without publishing the underlying database error.

Enums§

AggregateFn
AggregateKind
BucketRequest
CompatibilityPolicy
ConfigError
Errors in static entity or policy configuration.
CountStrategy
CursorValue
ExecutionStrategy
ExtensionError
FieldKind
Determines whether a condition is evaluated before or after grouping.
FilterOnlyKind
GroupKeyKind
LabelFailurePolicy
MissingLabelPolicy
NullOrder
Operator
M1 field operators.
PagingMode
ParamError
Errors caused by untrusted query parameters or programmatic user queries.
PgBindValue
PgSearchError
PlanError
Errors while combining a validated user query with server policy.
PoolRouteError
PredicateNode
PredicatePhase
Projection
QueryTarget
RenderError
ResultFilterDecision
RowValue
Dynamic result value. Unlike ScalarValue, this can represent SQL NULL.
ScalarKind
ScalarValue
A typed, non-null scalar used in predicates.
SchemaValidationTarget
What the schema contract validator checked.
SearchError
SnapshotIsolation
SortOrder
TimeBucketUnit
TimeoutStage
ValueType
Supported logical value types.

Traits§

Codec
A server-owned input/result conversion codec.
FieldConvertor
Compatibility name for reflection-based field converters. Implementations use the typed Codec contract and cannot bypass bind typing.
IntoCursorValue
IntoScalarValue
LabelLoader
LabelTarget
Typed opt-in: implementations explicitly name the source fields and writable label fields. set_label must not modify database fields or ordering keys.
PageEnricher
Asynchronous page-level result enhancement. Implementations should batch external lookups and must not change count, summaries, or cursor metadata.
PartitionResolver
PgPoolSelector
Application-owned, nonblocking resolver for trusted request context. Client query parameters are never supplied to this hook.
PgSumType
PgSummaryValue
QueryInput
QueryObserver
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.
RawParamFilter
A server-owned parameter normalization step.
ResultFilter
RowPhaseKind
ScopeProvider
Builds a server-owned authorization scope from a trusted request context.
SearchEntity
Implemented by derive-generated query entities.
SearchProjection
SqlInterceptor
SummableKind
TypedPageEnricher
Explicit typed opt-in: implementers declare which presentation fields may be filled and preserve database fields and ordering keys.

Functions§

public_error

Type Aliases§

ExtensionFuture
RowMap
ScanFuture
SearchStream

Derive Macros§

SearchEntity
SearchProjection