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}