Defining the search order

Version 0.3.0 Updated Jul 22, 2026

Set the search order of recursive CTEs (breadth or depth first) by chaining with_search onto with_recursive or with_recursive_not_all. Pass a single column name or a static list of column names to control the SEARCH ... BY ordering expression.

with_search is PostgreSQL-only. The builder remains available on recursive queries created by with_recursive or with_recursive_not_all, but walk_ast rejects a searched recursive CTE for SQLite and other non-PostgreSQL backends with QueryBuilderError instead of emitting unsupported SEARCH ... BY ... SET syntax.

use diesel::{dsl::sql, pg::PgConnection, sql_types::Integer, RunQueryDsl};
use diesel_cte_ext::{RecursiveCTEExt, RecursiveParts, SearchStyle};

fn reachable_nodes(conn: &mut PgConnection) -> diesel::QueryResult<Vec<i32>> {
    conn.with_recursive_not_all(
        "graph",
        &["node_id"],
        RecursiveParts::new(
            sql::<Integer>("SELECT 1"),
            sql::<Integer>(concat!(
            "SELECT edges.target_id FROM edges ",
            "INNER JOIN graph ON edges.source_id = graph.node_id"
            )),
            sql::<Integer>("SELECT node_id FROM graph ORDER BY ordercol"),
        ),
    ).with_search(SearchStyle::DepthFirst, &["node_id"], "ordercol")
        .load(conn)
}