From ca1595b98faa2e5eeb18757bdd0e11b14b980251 Mon Sep 17 00:00:00 2001 From: EmirVildanov <reddog201030@gmail.com> Date: Tue, 17 Sep 2024 13:31:19 +0300 Subject: [PATCH] fix: support case of several Relations referencing the same SubQuery in `take_subtree` --- sbroad-core/src/executor/ir.rs | 29 +++++++++++++++++-- .../transformation/redistribution/groupby.rs | 8 +++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/sbroad-core/src/executor/ir.rs b/sbroad-core/src/executor/ir.rs index 6e02205496..36125f1ddc 100644 --- a/sbroad-core/src/executor/ir.rs +++ b/sbroad-core/src/executor/ir.rs @@ -441,6 +441,30 @@ impl ExecutionPlan { } } + // TODO: See note in `add_local_projection` function about SubQueries + // to understand why we don't want to replace SubQueries with stubs sometimes. + // The reason is that several relational nodes may point to it as a child. + let sqs = nodes + .iter() + .map(|LevelNode(_, id)| *id) + .filter(|id| { + matches!( + plan.get_node(*id), + Ok(Node::Relational(Relational::ScanSubQuery(_))) + ) + }) + .collect::<Vec<_>>(); + let mut sq_ids: AHashSet<NodeId> = AHashSet::new(); + for sq_id in sqs { + let mut sq_subtree = PostOrder::with_capacity( + |node| plan.exec_plan_subtree_iter(node), + plan.nodes.len(), + ); + for LevelNode(_, id) in sq_subtree.iter(sq_id) { + sq_ids.insert(id); + } + } + let mut subtree_map = SubtreeMap::with_capacity(nodes.len()); let vtables_capacity = self.get_vtables().map_or_else(|| 1, HashMap::len); // Map of { plan node_id -> virtual table }. @@ -465,8 +489,9 @@ impl ExecutionPlan { let mut_plan = self.get_mut_ir_plan(); // Replace the node with some invalid value. - let mut node: NodeOwned = if cte_ids.contains(&node_id) { - mut_plan.get_node(node_id)?.get_common_node() + let node = mut_plan.get_node(node_id)?; + let mut node: NodeOwned = if cte_ids.contains(&node_id) || sq_ids.contains(&node_id) { + node.into_owned() } else { mut_plan.replace_with_stub(node_id) }; diff --git a/sbroad-core/src/ir/transformation/redistribution/groupby.rs b/sbroad-core/src/ir/transformation/redistribution/groupby.rs index 5c713c747b..c377275d64 100644 --- a/sbroad-core/src/ir/transformation/redistribution/groupby.rs +++ b/sbroad-core/src/ir/transformation/redistribution/groupby.rs @@ -1084,6 +1084,14 @@ impl Plan { if matches!(rel_node, Relational::ScanSubQuery { .. }) && self.is_additional_child(ref_rel_node_id)? { + // Note: For queries like `select sum((VALUES (1))) from t` it may be a problem + // that we don't make a copy of a SubQuery node, but just copy its id so that + // several Relational node consider it to be a child. + // It may be a problem on a `take_subtree` call for the query above: + // * `take_subtree` will replace SQ with Invalid while traversing Local(Map) + // stage + // * Later Final(Reduce) stage won't see the SubQuery. + // TODO: Solution would be to use `SubtreeCloner::clone`? children.push(ref_rel_node_id); } } -- GitLab