Skip to main content

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

1//! Immutable configuration for unary (one-input) operators.
2
3use linkrs_core::types::expr::Expression;
4use linkrs_core::DataType;
5
6/// Immutable config for unary (one-input) operators.
7#[derive(Debug, Clone)]
8pub enum UnarySpec {
9    Filter {
10        predicate: Expression,
11        /// Expression-level subqueries compiled for this filter;
12        /// the materializer turns them into a per-operator `SubqueryExecutor`.
13        subquery_runners: Vec<crate::executor::streaming::subquery::SubqueryRunnerSpec>,
14    },
15    Project {
16        output_expressions: Vec<Expression>,
17        output_col_names: Vec<String>,
18        /// Resolved per-column types from the planner (`ProjectNode.column_types`).
19        /// May be empty for hand-built plans; layouts fall back to untyped slots.
20        output_col_types: Vec<DataType>,
21        /// Expression-level subqueries compiled for this project.
22        subquery_runners: Vec<crate::executor::streaming::subquery::SubqueryRunnerSpec>,
23    },
24    Limit {
25        offset: u32,
26        limit: u32,
27    },
28    Assign {
29        assignments: Vec<(String, Expression)>,
30        /// Expression-level subqueries compiled for this assign.
31        subquery_runners: Vec<crate::executor::streaming::subquery::SubqueryRunnerSpec>,
32    },
33    Unwind {
34        unwind_column: String,
35        list_expression: Option<Expression>,
36    },
37    /// Storage-backed vertex property append.
38    ///
39    /// Evaluates `entity_expr` per input row to resolve the vertex id, reads
40    /// the vertex (full or projected) from storage, and appends the property
41    /// columns to the row.  With a non-empty `prop_names` the appended
42    /// columns are the flat `{entity_var}.{prop}` names; with an empty list
43    /// the whole `Value::Vertex` is appended under `entity_var`.
44    AppendVertices {
45        /// Space the vertex is read from.
46        space_name: String,
47        /// Single tag for forced single-label fetch.
48        tag: String,
49        /// Binding variable of the appended vertex (flat-column prefix).
50        entity_var: String,
51        /// Expression resolved per row to the vertex id.
52        entity_expr: Expression,
53        /// Property names to read; empty reads the full vertex.
54        prop_names: Vec<String>,
55    },
56    Sample {
57        count: u64,
58    },
59    Flatten {
60        group_pos: u32,
61        /// Alias names of the flattened group snapshotted at rewrite time.
62        ///
63        /// Traceability metadata only; the executor never validates these
64        /// names because the schema alias namespace and the runtime
65        /// column namespace are not identical.
66        group_columns: Vec<String>,
67        /// Group count of the child schema at rewrite time, when known.
68        ///
69        /// The executor rejects a stale `group_pos` (`group_pos` must be
70        /// below this count) loudly at `open()`. `None` means unknown
71        /// (hand-built or legacy plan) and skips the check honestly.
72        expected_groups: Option<u32>,
73    },
74}
75
76impl UnarySpec {
77    /// Expression-level subquery runner specs of this operator (empty for
78    /// kinds that do not host subqueries). The materializer instantiates a
79    /// per-operator `SubqueryExecutor` from these.
80    pub fn subquery_runners(&self) -> &[crate::executor::streaming::subquery::SubqueryRunnerSpec] {
81        match self {
82            Self::Filter {
83                subquery_runners, ..
84            }
85            | Self::Project {
86                subquery_runners, ..
87            }
88            | Self::Assign {
89                subquery_runners, ..
90            } => subquery_runners,
91            _ => &[],
92        }
93    }
94}