Skip to main content

linkrs_query/executor/streaming/operators/spec/
recursive.rs

1//! Immutable configuration for recursive fragment operators.
2
3use std::sync::Arc;
4
5use linkrs_core::{EdgeDirection, Value};
6
7use crate::executor::streaming::plan::types::PhysicalPlan;
8
9/// Immutable config for recursive fragment operators.
10///
11/// Variable-length path traversal, BFS, shortest-path, and multi-round
12/// graph algorithms use this explicit recursive fragment spec.
13///
14/// Frontier, visited-set, path-predecessor, and result-queue allocations
15/// are all accounted against the query memory pool.  Each round and
16/// batch-expansion checks the cancellation token.
17#[derive(Debug, Clone)]
18pub enum RecursiveFragmentSpec {
19    /// Bidirectional BFS shortest path between start and target vertices.
20    ///
21    /// When `weight` is set the search runs Dijkstra on that edge property
22    /// instead of hop-count BFS (see `algorithms::weighted_shortest_path`).
23    ShortestPath {
24        edge_types: Vec<String>,
25        direction: EdgeDirection,
26        max_depth: usize,
27        start_vertices: Vec<Value>,
28        target_vertices: Vec<Value>,
29        /// Single vertex label used to materialize path vertices.
30        vertex_tag: String,
31        /// Edge property used as the traversal weight (None = hop-count BFS).
32        weight: Option<String>,
33    },
34    /// Multi-source multi-target shortest path via bidirectional BFS.
35    MultiShortestPath {
36        edge_types: Vec<String>,
37        direction: EdgeDirection,
38        max_depth: usize,
39        left_vertex_column: String,
40        right_vertex_column: String,
41        single_shortest: bool,
42        /// Single vertex label used to materialize path vertices.
43        vertex_tag: String,
44    },
45    /// BFS traversal with configurable depth and cycle policies.
46    BFSShortest {
47        edge_types: Vec<String>,
48        direction: EdgeDirection,
49        max_depth: usize,
50        allow_loops: bool,
51        /// Single vertex label used to materialize path vertices.
52        vertex_tag: String,
53    },
54    /// Enumerate all paths between start and target vertices.
55    AllPaths {
56        edge_types: Vec<String>,
57        direction: EdgeDirection,
58        min_depth: usize,
59        max_depth: usize,
60        path_uniqueness:
61            crate::planning::plan::core::nodes::traversal::path_algorithms::PathUniqueness,
62        limit: Option<usize>,
63        offset: usize,
64        start_vertices: Vec<Value>,
65        target_vertices: Vec<Value>,
66        /// Single vertex label used to materialize path vertices.
67        vertex_tag: String,
68    },
69    /// Recursive-CTE fixpoint (`WITH [RECURSIVE] name AS (anchor [UNION ALL step])`).
70    ///
71    /// The anchor sub-plan runs once; the step sub-plan re-runs with the
72    /// previous delta published as the CTE working table (read through
73    /// [`CteScan`](super::source::SourceSpec::CteScan) sources keyed by the
74    /// mangled `cte_name`) until no new rows appear or `max_iterations` is
75    /// reached. `step` is `None` for a non-recursive CTE (inline view).
76    Fixpoint {
77        /// Mangled CTE tag (`crate::cte::mangle_cte_name`).
78        cte_name: String,
79        /// Anchor sub-plan (runs once, seeds the working table).
80        anchor: Arc<PhysicalPlan>,
81        /// Step sub-plan (re-runs per iteration over the delta).
82        step: Option<Arc<PhysicalPlan>>,
83        /// Fixpoint iteration cap (errors when exceeded).
84        max_iterations: u64,
85        /// Output column names (single column in V1).
86        col_names: Vec<String>,
87    },
88}