Skip to main content

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

1//! Immutable configuration for graph traversal operators.
2
3use linkrs_core::types::expr::Expression;
4use linkrs_core::{EdgeDirection, Value};
5
6use crate::parser::ast::pattern::PathSemantic;
7
8/// Immutable config for graph traversal operators.
9#[derive(Debug, Clone)]
10pub enum GraphSpec {
11    Expand {
12        edge_types: Vec<String>,
13        direction: EdgeDirection,
14        filter_expr: Option<Expression>,
15        col_names: Vec<String>,
16        dst_tag: String,
17    },
18    ExpandAll {
19        edge_types: Vec<String>,
20        direction: EdgeDirection,
21        filter_expr: Option<Expression>,
22        col_names: Vec<String>,
23        src_vids: Vec<Value>,
24        step_limit: u32,
25        step_limits: Option<Vec<u32>>,
26        /// When true, the expand operator only counts output rows instead of
27        /// materializing them. Used when the downstream is a simple COUNT(*)
28        /// aggregate with no GROUP BY or other aggregation functions.
29        count_only: bool,
30        /// When true, emit `Value::VertexId` / `Value::EdgeId` instead of
31        /// full `Value::Vertex(Box)` / `Value::Edge(Box)` in the expand
32        /// output.  Eliminates heap allocation for downstream operators that
33        /// only need the identifier (e.g. another expand hop, count, join key).
34        emit_raw_ids: bool,
35        /// When true (always alongside `emit_raw_ids`), the hop's source
36        /// column is also emitted as a `Value::VertexId` instead of cloning
37        /// the full `Value::Vertex(Box)` carried in from upstream.
38        lightweight_source: bool,
39        path_semantic: Option<PathSemantic>,
40        dst_tag: String,
41        /// Demanded edge properties (`None` means whole edge, empty means
42        /// topology only). Drives storage projection pushdown.
43        edge_required_props: Option<Vec<String>>,
44        /// Demanded destination properties, same encoding as the edge demand.
45        dst_required_props: Option<Vec<String>>,
46        /// Single-label closed loop proven by the planner syntactically and
47        /// re-verified against storage at execution with row fallback.
48        closed_loop: bool,
49        /// Rowless mode: skip the row view and emit typed columns only. Valid
50        /// with empty demands or with bypassable property demands served as
51        /// flat `{var}.{prop}` columns, always with a closed loop and a
52        /// column-capable consumer.
53        skip_rows: bool,
54        /// Whether seed vertices without any matching edge must still emit a
55        /// row (edge and destination projected as NULL). Used for OPTIONAL MATCH.
56        include_empty_paths: bool,
57    },
58    Traverse {
59        edge_types: Vec<String>,
60        direction: EdgeDirection,
61        min_depth: u32,
62        max_depth: u32,
63        filter_expr: Option<Expression>,
64        path_semantic: Option<PathSemantic>,
65        dst_tag: String,
66    },
67    BiExpand {
68        edge_types: Vec<String>,
69        direction: EdgeDirection,
70        dst_tag: String,
71    },
72    BiTraverse {
73        edge_types: Vec<String>,
74        direction: EdgeDirection,
75        min_depth: u32,
76        max_depth: u32,
77        dst_tag: String,
78    },
79}