Execute a hash-based expand operation with specific graph
(
&self,
from_variable: &str,
edge_variable: Option<&str>,
to_variable: &str,
edge_labels: &[String],
direction: &EdgeDirection,
properties: Opt
| 6180 | |
| 6181 | /// Execute a hash-based expand operation with specific graph |
| 6182 | fn execute_hash_expand_with_graph( |
| 6183 | &self, |
| 6184 | from_variable: &str, |
| 6185 | edge_variable: Option<&str>, |
| 6186 | to_variable: &str, |
| 6187 | edge_labels: &[String], |
| 6188 | direction: &EdgeDirection, |
| 6189 | properties: Option<&HashMap<String, Expression>>, |
| 6190 | input_rows: Vec<Row>, |
| 6191 | _context: &mut ExecutionContext, |
| 6192 | graph: &Arc<GraphCache>, |
| 6193 | ) -> Result<Vec<Row>, ExecutionError> { |
| 6194 | let mut result_rows = Vec::new(); |
| 6195 | |
| 6196 | for input_row in input_rows.iter() { |
| 6197 | // Get the from_variable node ID from the input row |
| 6198 | let from_node_id = input_row.get_value(from_variable).ok_or_else(|| { |
| 6199 | ExecutionError::RuntimeError(format!("Variable not found: {}", from_variable)) |
| 6200 | })?; |
| 6201 | |
| 6202 | // Extract node ID from either String or Node value |
| 6203 | let from_id = match from_node_id { |
| 6204 | Value::String(id) => id, |
| 6205 | Value::Node(node) => &node.id, |
| 6206 | _ => continue, // Skip this row if node ID can't be extracted |
| 6207 | }; |
| 6208 | |
| 6209 | { |
| 6210 | // Find edges based on direction |
| 6211 | let edges = match direction { |
| 6212 | EdgeDirection::Outgoing => graph.get_outgoing_edges(from_id), |
| 6213 | EdgeDirection::Incoming => graph.get_incoming_edges(from_id), |
| 6214 | EdgeDirection::Both => { |
| 6215 | // Handle both directions - this is the key fix! |
| 6216 | let mut both_edges = graph.get_outgoing_edges(from_id); |
| 6217 | both_edges.extend(graph.get_incoming_edges(from_id)); |
| 6218 | both_edges |
| 6219 | } |
| 6220 | EdgeDirection::Undirected => { |
| 6221 | // For undirected, treat as both directions |
| 6222 | let mut undirected_edges = graph.get_outgoing_edges(from_id); |
| 6223 | undirected_edges.extend(graph.get_incoming_edges(from_id)); |
| 6224 | undirected_edges |
| 6225 | } |
| 6226 | }; |
| 6227 | |
| 6228 | // Filter edges by labels if specified |
| 6229 | let filtered_edges: Vec<_> = if edge_labels.is_empty() { |
| 6230 | edges |
| 6231 | } else { |
| 6232 | edges |
| 6233 | .into_iter() |
| 6234 | .filter(|edge| edge_labels.iter().any(|label| &edge.label == label)) |
| 6235 | .collect() |
| 6236 | }; |
| 6237 | |
| 6238 | // Create result rows for each matching edge |
| 6239 | for edge in filtered_edges { |
no test coverage detected