@@ -22,9 +22,9 @@ use arrow::ffi_stream::ArrowArrayStreamReader;
2222use arrow_array:: { RecordBatch , RecordBatchReader } ;
2323use arrow_schema:: Schema ;
2424use lance_graph:: {
25- ExecutionStrategy as RustExecutionStrategy , CypherQuery as RustCypherQuery ,
26- GraphConfig as RustGraphConfig , GraphError as RustGraphError ,
27- VectorSearch as RustVectorSearch , ast :: DistanceMetric as RustDistanceMetric ,
25+ ast :: DistanceMetric as RustDistanceMetric , CypherQuery as RustCypherQuery ,
26+ ExecutionStrategy as RustExecutionStrategy , GraphConfig as RustGraphConfig ,
27+ GraphError as RustGraphError , VectorSearch as RustVectorSearch ,
2828} ;
2929use pyo3:: {
3030 exceptions:: { PyNotImplementedError , PyRuntimeError , PyValueError } ,
@@ -34,6 +34,7 @@ use pyo3::{
3434} ;
3535use serde_json:: Value as JsonValue ;
3636
37+ use crate :: namespace:: PyDirNamespace ;
3738use crate :: RT ;
3839
3940/// Execution strategy for Cypher queries
@@ -537,6 +538,45 @@ impl CypherQuery {
537538 record_batch_to_python_table ( py, & result_batch)
538539 }
539540
541+ /// Execute query using a namespace resolver.
542+ ///
543+ /// Parameters
544+ /// ----------
545+ /// namespace : DirNamespace
546+ /// Directory-backed namespace that resolves table names to Lance datasets.
547+ /// strategy : ExecutionStrategy, optional
548+ /// Execution strategy to use (defaults to DataFusion)
549+ ///
550+ /// Returns
551+ /// -------
552+ /// pyarrow.Table
553+ /// Query results as Arrow table
554+ ///
555+ /// Raises
556+ /// ------
557+ /// RuntimeError
558+ /// If query execution fails
559+ #[ pyo3( signature = ( namespace, strategy=None ) ) ]
560+ fn execute_with_namespace (
561+ & self ,
562+ py : Python ,
563+ namespace : & Bound < ' _ , PyDirNamespace > ,
564+ strategy : Option < ExecutionStrategy > ,
565+ ) -> PyResult < PyObject > {
566+ let rust_strategy = strategy. map ( |s| s. into ( ) ) ;
567+ let inner_query = self . inner . clone ( ) ;
568+ let namespace_arc = namespace. borrow ( ) . inner . clone ( ) ;
569+
570+ let result_batch = RT
571+ . block_on (
572+ Some ( py) ,
573+ inner_query. execute_with_namespace_arc ( namespace_arc, rust_strategy) ,
574+ ) ?
575+ . map_err ( graph_error_to_pyerr) ?;
576+
577+ record_batch_to_python_table ( py, & result_batch)
578+ }
579+
540580 /// Explain query using the DataFusion planner with in-memory datasets
541581 ///
542582 /// Parameters
@@ -641,7 +681,10 @@ impl CypherQuery {
641681
642682 // Execute via runtime
643683 let result = RT
644- . block_on ( Some ( py) , inner_query. execute_with_vector_rerank ( arrow_datasets, vs) ) ?
684+ . block_on (
685+ Some ( py) ,
686+ inner_query. execute_with_vector_rerank ( arrow_datasets, vs) ,
687+ ) ?
645688 . map_err ( graph_error_to_pyerr) ?;
646689
647690 record_batch_to_python_table ( py, & result)
@@ -840,6 +883,7 @@ pub fn register_graph_module(py: Python, parent_module: &Bound<'_, PyModule>) ->
840883 graph_module. add_class :: < GraphConfigBuilder > ( ) ?;
841884 graph_module. add_class :: < CypherQuery > ( ) ?;
842885 graph_module. add_class :: < VectorSearch > ( ) ?;
886+ graph_module. add_class :: < PyDirNamespace > ( ) ?;
843887
844888 parent_module. add_submodule ( & graph_module) ?;
845889 Ok ( ( ) )
0 commit comments