@@ -17,6 +17,23 @@ mod clauses;
1717mod expr;
1818mod simple_executor;
1919
20+ /// Execution strategy for Cypher queries
21+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
22+ pub enum ExecutionStrategy {
23+ /// Use DataFusion query planner (default, full feature support)
24+ DataFusion ,
25+ /// Use simple single-table executor (legacy, limited features)
26+ Simple ,
27+ /// Use Lance native executor (not yet implemented)
28+ LanceNative ,
29+ }
30+
31+ impl Default for ExecutionStrategy {
32+ fn default ( ) -> Self {
33+ Self :: DataFusion
34+ }
35+ }
36+
2037/// A Cypher query that can be executed against Lance datasets
2138#[ derive( Debug , Clone ) ]
2239pub struct CypherQuery {
@@ -92,6 +109,68 @@ impl CypherQuery {
92109 } )
93110 }
94111
112+ /// Execute the query against provided in-memory datasets
113+ ///
114+ /// This method uses the DataFusion planner by default for comprehensive query support
115+ /// including joins, aggregations, and complex patterns. You can optionally specify
116+ /// a different execution strategy.
117+ ///
118+ /// # Arguments
119+ /// * `datasets` - HashMap of table name to RecordBatch (nodes and relationships)
120+ /// * `strategy` - Optional execution strategy (defaults to DataFusion)
121+ ///
122+ /// # Returns
123+ /// A single RecordBatch containing the query results
124+ ///
125+ /// # Errors
126+ /// Returns error if query parsing, planning, or execution fails
127+ ///
128+ /// # Example
129+ /// ```ignore
130+ /// use std::collections::HashMap;
131+ /// use arrow::record_batch::RecordBatch;
132+ /// use lance_graph::query::CypherQuery;
133+ ///
134+ /// // Create in-memory datasets
135+ /// let mut datasets = HashMap::new();
136+ /// datasets.insert("Person".to_string(), person_batch);
137+ /// datasets.insert("KNOWS".to_string(), knows_batch);
138+ ///
139+ /// // Parse and execute query
140+ /// let query = CypherQuery::parse("MATCH (p:Person)-[:KNOWS]->(f) RETURN p.name, f.name")?
141+ /// .with_config(config);
142+ /// // Use the default DataFusion strategy
143+ /// let result = query.execute(datasets, None).await?;
144+ /// // Use the Simple strategy explicitly
145+ /// let result = query.execute(datasets, Some(ExecutionStrategy::Simple)).await?;
146+ /// ```
147+ pub async fn execute (
148+ & self ,
149+ datasets : HashMap < String , arrow:: record_batch:: RecordBatch > ,
150+ strategy : Option < ExecutionStrategy > ,
151+ ) -> Result < arrow:: record_batch:: RecordBatch > {
152+ let strategy = strategy. unwrap_or_default ( ) ;
153+ match strategy {
154+ ExecutionStrategy :: DataFusion => self . execute_datafusion ( datasets) . await ,
155+ ExecutionStrategy :: Simple => self . execute_simple ( datasets) . await ,
156+ ExecutionStrategy :: LanceNative => Err ( GraphError :: UnsupportedFeature {
157+ feature : "Lance native execution strategy is not yet implemented" . to_string ( ) ,
158+ location : snafu:: Location :: new ( file ! ( ) , line ! ( ) , column ! ( ) ) ,
159+ } ) ,
160+ }
161+ }
162+
163+ /// Explain the query execution plan using the DataFusion planner
164+ ///
165+ /// This method provides a high-level overview of the query execution plan
166+ /// using the DataFusion planner, which is useful for debugging and optimization.
167+ pub async fn explain (
168+ & self ,
169+ datasets : HashMap < String , arrow:: record_batch:: RecordBatch > ,
170+ ) -> Result < String > {
171+ self . explain_datafusion ( datasets) . await
172+ }
173+
95174 /// Execute using the DataFusion planner with in-memory datasets
96175 ///
97176 /// # Overview
@@ -601,30 +680,6 @@ impl CypherQuery {
601680 Ok ( output)
602681 }
603682
604- /// Execute the query against provided in-memory datasets using the DataFusion planner
605- ///
606- /// This is the primary execution method that uses the full DataFusion-based planner
607- /// for comprehensive query support including joins, aggregations, and complex patterns.
608- ///
609- /// For legacy single-table queries, use `execute_simple()` instead.
610- pub async fn execute (
611- & self ,
612- datasets : HashMap < String , arrow:: record_batch:: RecordBatch > ,
613- ) -> Result < arrow:: record_batch:: RecordBatch > {
614- self . execute_datafusion ( datasets) . await
615- }
616-
617- /// Explain the query execution plan using the DataFusion planner
618- ///
619- /// This method provides a high-level overview of the query execution plan
620- /// using the DataFusion planner, which is useful for debugging and optimization.
621- pub async fn explain (
622- & self ,
623- datasets : HashMap < String , arrow:: record_batch:: RecordBatch > ,
624- ) -> Result < String > {
625- self . explain_datafusion ( datasets) . await
626- }
627-
628683 /// Execute simple single-table queries (legacy implementation)
629684 ///
630685 /// This method supports basic projection/filter/limit workflows on a single table.
0 commit comments