Skip to main content

query_lazy

Macro query_lazy 

Source
query_lazy!() { /* proc-macro */ }
Expand description

Type-safe SQL macro that builds a lazy query and returns a stream on execution.

Like query!, this macro validates table/column names and binds arguments at compile time, but it does not execute immediately. Instead it returns a lazy query builder that can be stored, moved, and executed later.

? (handling result) is required to build the lazy query.

§Syntax

query_lazy!(<Driver> SQL)
  • <Driver> is optional; if omitted the default driver is taken from the build script via sql_build::build. If multiple (or zero) defaults are configured, you must specify the driver explicitly.
  • Uses the same SQL syntax and helpers as query!
  • There is no connection parameter in the macro call; pass it when fetching.

§Return value

returns a anyhow::Result<LazyQueryResult> with the following methods:

  • fetch(impl EasyExecutor) - use when you have a concrete connection/transaction type
  • fetch_mut(&mut impl EasyExecutor) - use when you have a generic &mut impl EasyExecutor

Both return futures::Stream<Item = anyhow::Result<Output>>. The stream borrows the connection; drop or fully consume it before reusing the connection.

§Output and query forms

  • Output must be a single-row type implementing Output. To return multiple rows, iterate/collect the stream yourself.
  • Supported query forms: SELECT, INSERT, UPDATE, DELETE.
  • INSERT/UPDATE/DELETE must include RETURNING (because results are streamed).
  • EXISTS is not supported; use query! instead.

§Examples

let mut lazy = query_lazy!(<Sqlite> SELECT OutputType FROM TableType WHERE column = 42)?;
let mut stream = lazy.fetch(&mut conn);
let row = stream.next().await.context("Expected at least one row")?;
let row = row.context("Failed to fetch row")?;
let min_val = 10;
let mut lazy = query_lazy!(
    SELECT ExprTestData FROM ExprTestTable WHERE ExprTestTable.int_field > {min_val}
)?;

let mut rows = Vec::new();
let mut stream = lazy.fetch(&mut conn);
while let Some(row) = stream.next().await {
    rows.push(row.context("Failed to fetch row")?);
}
async fn generic_executor_example(
    conn: &mut impl EasyExecutor<ExampleDriver>,
) -> anyhow::Result<()> {
    let mut lazy = query_lazy!(SELECT ExprTestData FROM ExprTestTable)?;
    let mut stream = lazy.fetch_mut(conn);
    let maybe = stream.next().await.transpose()?;
    assert!(maybe.is_some());
    Ok(())
}