Skip to main content

grafeo_core/execution/operators/
mod.rs

1//! Physical operators that actually execute queries.
2//!
3//! These are the building blocks of query execution. The optimizer picks which
4//! operators to use and how to wire them together.
5//!
6//! **Graph operators:**
7//! - [`ScanOperator`] - Read nodes/edges from storage
8//! - [`ExpandOperator`] - Traverse edges (the core of graph queries)
9//! - [`VariableLengthExpandOperator`] - Paths of variable length
10//! - [`ShortestPathOperator`] - Find shortest paths
11//!
12//! **Relational operators:**
13//! - [`FilterOperator`] - Apply predicates
14//! - [`ProjectOperator`] - Select/transform columns
15//! - [`HashJoinOperator`] - Efficient equi-joins
16//! - [`HashAggregateOperator`] - Group by with aggregation
17//! - [`SortOperator`] - Order results
18//! - [`LimitOperator`] - SKIP and LIMIT
19//!
20//! The [`push`] submodule has push-based variants for pipeline execution.
21
22mod aggregate;
23mod distinct;
24mod expand;
25mod filter;
26mod join;
27mod limit;
28mod merge;
29mod mutation;
30mod project;
31pub mod push;
32mod scan;
33mod shortest_path;
34pub mod single_row;
35mod sort;
36mod union;
37mod unwind;
38mod variable_length_expand;
39
40pub use aggregate::{
41    AggregateExpr, AggregateFunction, HashAggregateOperator, SimpleAggregateOperator,
42};
43pub use distinct::DistinctOperator;
44pub use expand::ExpandOperator;
45pub use filter::{
46    BinaryFilterOp, ExpressionPredicate, FilterExpression, FilterOperator, Predicate, UnaryFilterOp,
47};
48pub use join::{
49    EqualityCondition, HashJoinOperator, HashKey, JoinCondition, JoinType, NestedLoopJoinOperator,
50};
51pub use limit::{LimitOperator, LimitSkipOperator, SkipOperator};
52pub use merge::MergeOperator;
53pub use mutation::{
54    AddLabelOperator, CreateEdgeOperator, CreateNodeOperator, DeleteEdgeOperator,
55    DeleteNodeOperator, PropertySource, RemoveLabelOperator, SetPropertyOperator,
56};
57pub use project::{ProjectExpr, ProjectOperator};
58pub use push::{
59    AggregatePushOperator, DistinctMaterializingOperator, DistinctPushOperator, FilterPushOperator,
60    LimitPushOperator, ProjectPushOperator, SkipLimitPushOperator, SkipPushOperator,
61    SortPushOperator, SpillableAggregatePushOperator, SpillableSortPushOperator,
62};
63pub use scan::ScanOperator;
64pub use shortest_path::ShortestPathOperator;
65pub use sort::{NullOrder, SortDirection, SortKey, SortOperator};
66pub use union::UnionOperator;
67pub use unwind::UnwindOperator;
68pub use variable_length_expand::VariableLengthExpandOperator;
69
70use thiserror::Error;
71
72use super::DataChunk;
73
74/// Result of executing an operator.
75pub type OperatorResult = Result<Option<DataChunk>, OperatorError>;
76
77/// Error during operator execution.
78#[derive(Error, Debug, Clone)]
79pub enum OperatorError {
80    /// Type mismatch during execution.
81    #[error("type mismatch: expected {expected}, found {found}")]
82    TypeMismatch {
83        /// Expected type name.
84        expected: String,
85        /// Found type name.
86        found: String,
87    },
88    /// Column not found.
89    #[error("column not found: {0}")]
90    ColumnNotFound(String),
91    /// Execution error.
92    #[error("execution error: {0}")]
93    Execution(String),
94}
95
96/// The core trait for pull-based operators.
97///
98/// Call [`next()`](Self::next) repeatedly until it returns `None`. Each call
99/// returns a batch of rows (a DataChunk) or an error.
100pub trait Operator: Send + Sync {
101    /// Pulls the next batch of data. Returns `None` when exhausted.
102    fn next(&mut self) -> OperatorResult;
103
104    /// Resets to initial state so you can iterate again.
105    fn reset(&mut self);
106
107    /// Returns a name for debugging/explain output.
108    fn name(&self) -> &'static str;
109}