diff --git a/src/executor/engine/cartridge/backend/sql/ir.rs b/src/executor/engine/cartridge/backend/sql/ir.rs index 70d04d8b9da91e2bd270e07dca3f4b8ef401794c..4f0bbb0479d0cea180ea63ed382ee9a7718bbc51 100644 --- a/src/executor/engine/cartridge/backend/sql/ir.rs +++ b/src/executor/engine/cartridge/backend/sql/ir.rs @@ -168,15 +168,8 @@ impl ExecutionPlan { })?; } Expression::Reference { position, .. } => { - let rel_id: usize = ir_plan - .get_relational_from_reference_node(*id)? - .into_iter() - .next() - .ok_or_else(|| { - QueryPlannerError::CustomError( - "Reference points to a non-relational node.".into(), - ) - })?; + let rel_id: usize = + ir_plan.get_relational_from_reference_node(*id)?; let rel_node = ir_plan.get_relation_node(rel_id)?; let alias = &ir_plan.get_alias_from_reference_node(expr)?; diff --git a/src/ir/explain.rs b/src/ir/explain.rs index 7536863786bbd7bb5e2bf32d1ed05dbc573dbcba..b25ab54856b54b33c79f0d83dcfe5c527c8c1ff1 100644 --- a/src/ir/explain.rs +++ b/src/ir/explain.rs @@ -47,15 +47,7 @@ impl Col { ))); } Expression::Reference { position, .. } => { - let rel_id: usize = plan - .get_relational_from_reference_node(*id)? - .into_iter() - .next() - .ok_or_else(|| { - QueryPlannerError::CustomError( - "Reference doesn't have child relation node".into(), - ) - })?; + let rel_id: usize = plan.get_relational_from_reference_node(*id)?; let rel_node = plan.get_relation_node(rel_id)?; let alias = plan.get_alias_from_reference_node(current_node)?; @@ -236,15 +228,7 @@ impl Row { ))); } Expression::Reference { position, .. } => { - let rel_id: usize = plan - .get_relational_from_reference_node(*child)? - .into_iter() - .next() - .ok_or_else(|| { - QueryPlannerError::CustomError( - "Reference doesn't have a child relation node.".into(), - ) - })?; + let rel_id: usize = plan.get_relational_from_reference_node(*child)?; let rel_node = plan.get_relation_node(rel_id)?; diff --git a/src/ir/expression.rs b/src/ir/expression.rs index 850d5c9147fd3c9d7cfefbf9faef1db812507725..d56e2be3b55b15bdf791e8c27c69c3938ff65530 100644 --- a/src/ir/expression.rs +++ b/src/ir/expression.rs @@ -682,7 +682,6 @@ impl Plan { } /// A list of relational nodes that makes up the reference. - /// For references in the scan node /// /// # Errors /// - reference is invalid @@ -690,7 +689,7 @@ impl Plan { pub fn get_relational_from_reference_node( &self, ref_id: usize, - ) -> Result<HashSet<usize, RandomState>, QueryPlannerError> { + ) -> Result<usize, QueryPlannerError> { if let Node::Expression(Expression::Reference { targets, parent, .. }) = self.get_node(ref_id)? @@ -700,20 +699,30 @@ impl Plan { ))?; let rel = self.get_relation_node(referred_rel_id)?; if let Relational::Insert { .. } = rel { - let mut rel_nodes: HashSet<usize, RandomState> = - HashSet::with_capacity_and_hasher(1, RandomState::new()); - rel_nodes.insert(referred_rel_id); - return Ok(rel_nodes); + return Ok(referred_rel_id); } else if let Some(children) = rel.children() { - if let Some(positions) = targets { - let mut rel_nodes: HashSet<usize, RandomState> = - HashSet::with_capacity_and_hasher(positions.len(), RandomState::new()); - for pos in positions { - if let Some(child) = children.get(*pos) { - rel_nodes.insert(*child); - } + match targets { + None => { + return Err(QueryPlannerError::CustomError( + "Reference node has no targets".into(), + )) } - return Ok(rel_nodes); + Some(positions) => match (positions.get(0), positions.get(1)) { + (Some(first), None) => { + let child_id = *children.get(*first).ok_or_else(|| { + QueryPlannerError::CustomError( + "Relational node has no child at first position".into(), + ) + })?; + return Ok(child_id); + } + _ => { + return Err(QueryPlannerError::CustomError( + "Reference expected to point exactly a single relational node" + .into(), + )) + } + }, } } } diff --git a/src/ir/operator.rs b/src/ir/operator.rs index be11832eb3c6d501fc0680145375cc0216e0d486..744ad97b5fe82b7b49deb3f68b743db56378b424 100644 --- a/src/ir/operator.rs +++ b/src/ir/operator.rs @@ -410,12 +410,8 @@ impl Relational { if let Expression::Alias { child, .. } = col_node { let child_node = plan.get_expression_node(*child)?; if let Expression::Reference { position: pos, .. } = child_node { - let rel_ids = plan.get_relational_from_reference_node(*child)?; - let rel_node = plan.get_relation_node( - rel_ids.into_iter().next().ok_or_else(|| { - QueryPlannerError::CustomError(String::from("No relational node")) - })?, - )?; + let rel_id = plan.get_relational_from_reference_node(*child)?; + let rel_node = plan.get_relation_node(rel_id)?; return rel_node.scan_name(plan, *pos); } } else {