Announcing spice-rs v4.0.0 π
v4.0.0 adds asynchronous query jobs, dataset refresh, mutual TLS, natural-language-to-SQL (Nsql), embedding search, active-query management, and parameterized queries β and makes one breaking change: Client::query() now submits a query for asynchronous execution instead of streaming it synchronously.
What's New
Parameterized queries and dataset refresh
Client::sql_with_bindings()for common scalar parameter types viaQueryParameters, orQueryParameter::array(...)to bind any Arrow array type directly.Client::refresh_dataset()/refresh_dataset_with_options()to trigger an accelerated dataset refresh, with control over refresh SQL, mode, and jitter.- The SDK now re-exports
arrowasspiceai::arrow, so parameter and result types stay aligned with the SDK's own Arrow version.
Mutual TLS
ClientBuilder::tls_client_certificate_file() and tls_client_key_file() (both required together) present a client certificate; tls_ca_certificate_file() verifies the server against a custom CA.
Natural language to SQL (Nsql)
Client::nsql(request) translates a natural-language query into SQL via the runtime's configured LLM and runs it, returning the rows alongside the generated SQL. Client::nsql_generate_sql(request) generates the SQL without running it β inspect or edit it, or run it through sql() for Arrow-typed results instead of nsql()'s decoded JSON rows.
Search
Client::search(request) finds documents similar to a piece of text via the runtime's /v1/search endpoint (vector, keyword, and hybrid search), for datasets with an embedding column and a loaded embedding model. Requires http_url() to be configured.
Active query management
Client::active_queries() lists synchronous queries currently running on the runtime, and Client::cancel_active_query(id) cancels one β the runtime doesn't hand a query's ID back to the client that submitted it, so listing is the only way to discover the ID cancellation needs. Distinct from QueryJob::cancel(), which cancels an async job.
Runtime status
Client::runtime_status() reports the state of each runtime connection (http, flight, metrics, opentelemetry) individually; Client::is_ready() remains the simple boolean check.
Reliability fixes
- The Flight connection is now established lazily, so an HTTP-only client (one that never calls
sql()/query()/sql_with_bindings()) no longer requires a reachable Flight endpoint at construction time. - The configured API key is now kept only on the origin it was set for, rather than following a redirect to a different host.
Breaking Changes
Client::query() / Client::query_with_bindings() are now asynchronous.
In prior releases, query() was a synchronous alias that streamed results directly. It now submits the query for async execution against the runtime's /v1/queries API and returns a QueryJob handle.
// Old (v3.x) β query() streamed results directly
let mut stream = client.query("SELECT * FROM taxi_trips LIMIT 10").await?;
while let Some(batch) = stream.next().await {
// ...
}
// New (v4.0.0) β use sql() for the same synchronous, streaming behavior
let mut stream = client.sql("SELECT * FROM taxi_trips LIMIT 10").await?;
while let Some(batch) = stream.next().await {
// ...
}
// New (v4.0.0) β query() now submits an async job
let job = client.query("SELECT * FROM taxi_trips LIMIT 10").await?;
let batches = job.results().await?; // waits for completion, then fetches resultsquery_with_bindings() follows the same pattern β use sql_with_bindings() for the old synchronous behavior. sql(), sql_with_params(), and sql_with_bindings() are otherwise unchanged from v3.x.
QueryJob provides: id(), status(), info(), wait(), wait_timeout(duration), results(), results_stream(), and cancel(). Client::get_query(id) rehydrates a QueryJob handle from a previously-submitted query ID, and Client::queries(status_filter, limit) lists submitted jobs. Async query jobs require http_url() to be configured and the runtime to be running in cluster/scheduler mode.
Dependency upgrades
Arrow and arrow-flight upgraded to 58.3 (matching DataFusion v54), tonic to 0.14, Rust toolchain to 1.93.1.
Full Changelog: v3.0.0...v4.0.0