Skip to content
Snippets Groups Projects
Commit 05470fd5 authored by Denis Smirnov's avatar Denis Smirnov
Browse files

fix: gather only booleans with row children

parent 4f13ef13
No related branches found
No related tags found
1 merge request!1414sbroad import
...@@ -63,17 +63,31 @@ impl Plan { ...@@ -63,17 +63,31 @@ impl Plan {
Ok(nodes) Ok(nodes)
} }
/// Get boolean expressions in the sub-tree. /// Get boolean expressions with row children in the sub-tree.
/// ///
/// # Errors /// # Errors
/// - some of the expression nodes are invalid /// - some of the expression nodes are invalid
fn get_bool_nodes_dfs_post(&self, top: usize) -> Result<Vec<usize>, QueryPlannerError> { fn get_bool_nodes_with_row_children(
&self,
top: usize,
) -> Result<Vec<usize>, QueryPlannerError> {
let mut nodes: Vec<usize> = Vec::new(); let mut nodes: Vec<usize> = Vec::new();
let post_tree = DftPost::new(&top, |node| self.nodes.expr_iter(node, false)); let post_tree = DftPost::new(&top, |node| self.nodes.expr_iter(node, false));
for (_, node) in post_tree { for (_, node) in post_tree {
if let Node::Expression(Expression::Bool { .. }) = self.get_node(*node)? { // Append only booleans with row children.
nodes.push(*node); if let Node::Expression(Expression::Bool { left, right, .. }) = self.get_node(*node)? {
let left_is_row = matches!(
self.get_node(*left)?,
Node::Expression(Expression::Row { .. })
);
let right_is_row = matches!(
self.get_node(*right)?,
Node::Expression(Expression::Row { .. })
);
if left_is_row && right_is_row {
nodes.push(*node);
}
} }
} }
Ok(nodes) Ok(nodes)
...@@ -197,7 +211,7 @@ impl Plan { ...@@ -197,7 +211,7 @@ impl Plan {
expr_id: usize, expr_id: usize,
map: &HashMap<usize, usize>, map: &HashMap<usize, usize>,
) -> Result<HashMap<usize, MotionPolicy>, QueryPlannerError> { ) -> Result<HashMap<usize, MotionPolicy>, QueryPlannerError> {
let nodes = self.get_bool_nodes_dfs_post(expr_id)?; let nodes = self.get_bool_nodes_with_row_children(expr_id)?;
for node in &nodes { for node in &nodes {
let bool_op = BoolOp::from_expr(self, *node)?; let bool_op = BoolOp::from_expr(self, *node)?;
self.set_distribution(bool_op.left, map)?; self.set_distribution(bool_op.left, map)?;
...@@ -292,6 +306,8 @@ impl Plan { ...@@ -292,6 +306,8 @@ impl Plan {
} }
} }
} }
// TODO: gather motions (revert bft)
Ok(()) Ok(())
} }
} }
......
...@@ -231,3 +231,76 @@ fn local_sub_query() { ...@@ -231,3 +231,76 @@ fn local_sub_query() {
let expected_plan = Plan::from_yaml(&s).unwrap(); let expected_plan = Plan::from_yaml(&s).unwrap();
assert_eq!(plan, expected_plan); assert_eq!(plan, expected_plan);
} }
#[test]
fn multiple_sub_queries() {
// t1(a int) key [a]
// t2(a int, b int) key [a]
// select * from t1 where a < (select a from t2) or a = (select b from t2)
let mut plan = Plan::new();
let mut children: Vec<usize> = Vec::new();
let t1 = Table::new_seg("t1", vec![Column::new("a", Type::Integer)], &["a"]).unwrap();
plan.add_rel(t1);
let scan_t1_id = plan.add_scan("t1").unwrap();
children.push(scan_t1_id);
let t2 = Table::new_seg(
"t2",
vec![
Column::new("a", Type::Integer),
Column::new("b", Type::Integer),
],
&["a"],
)
.unwrap();
plan.add_rel(t2);
let sq1_scan_t2_id = plan.add_scan("t2").unwrap();
let sq1_proj_id = plan.add_proj(sq1_scan_t2_id, &["a"]).unwrap();
let sq1_id = plan.add_sub_query(sq1_proj_id, None).unwrap();
children.push(sq1_id);
let sq1_pos = children.len() - 1;
let sq2_scan_t2_id = plan.add_scan("t2").unwrap();
let sq2_proj_id = plan.add_proj(sq2_scan_t2_id, &["b"]).unwrap();
let sq2_id = plan.add_sub_query(sq2_proj_id, None).unwrap();
children.push(sq2_id);
let sq2_pos = children.len() - 1;
let id = plan.nodes.next_id();
let sq1_inner_a_id = plan
.add_row_from_sub_query(id, &children[..], sq1_pos, &["a"])
.unwrap();
let sq1_outer_a_id = plan.add_row_from_child(id, scan_t1_id, &["a"]).unwrap();
let less_id = plan
.add_bool(sq1_outer_a_id, Bool::Lt, sq1_inner_a_id)
.unwrap();
let sq2_inner_a_id = plan
.add_row_from_sub_query(id, &children[..], sq2_pos, &["b"])
.unwrap();
let sq2_outer_a_id = plan.add_row_from_child(id, scan_t1_id, &["a"]).unwrap();
let eq_id = plan
.add_bool(sq2_outer_a_id, Bool::Eq, sq2_inner_a_id)
.unwrap();
let or_id = plan.add_bool(less_id, Bool::Or, eq_id).unwrap();
let select_id = plan.add_select(&children[..], or_id, id).unwrap();
plan.set_top(select_id).unwrap();
plan.add_motions().unwrap();
// Check the modified plan
plan.nodes.add_new_equalities().unwrap();
let path = Path::new("")
.join("tests")
.join("artifactory")
.join("ir")
.join("transformation")
.join("redistribution")
.join("multiple_sub_queries.yaml");
let s = fs::read_to_string(path).unwrap();
let expected_plan = Plan::from_yaml(&s).unwrap();
assert_eq!(plan, expected_plan);
}
---
nodes:
arena:
- Expression:
Reference:
targets: ~
position: 0
parent: 0
- Expression:
Alias:
name: a
child: 0
- Expression:
Row:
list:
- 1
distribution:
Segment:
keys:
- positions:
- 0
- Relational:
ScanRelation:
output: 2
id: 0
relation: t1
- Expression:
Reference:
targets: ~
position: 0
parent: 4
- Expression:
Alias:
name: a
child: 4
- Expression:
Reference:
targets: ~
position: 1
parent: 4
- Expression:
Alias:
name: b
child: 6
- Expression:
Row:
list:
- 5
- 7
distribution:
Segment:
keys:
- positions:
- 0
- Relational:
ScanRelation:
output: 8
id: 4
relation: t2
- Expression:
Reference:
targets:
- 0
position: 0
parent: 10
- Expression:
Alias:
name: a
child: 10
- Expression:
Row:
list:
- 11
distribution:
Segment:
keys:
- positions:
- 0
- Relational:
Projection:
children:
- 9
id: 10
output: 12
- Expression:
Reference:
targets:
- 0
position: 0
parent: 14
- Expression:
Alias:
name: a
child: 14
- Expression:
Row:
list:
- 15
distribution:
Segment:
keys:
- positions:
- 0
- Relational:
ScanSubQuery:
alias: ~
children:
- 13
id: 14
output: 16
- Expression:
Reference:
targets: ~
position: 0
parent: 18
- Expression:
Alias:
name: a
child: 18
- Expression:
Reference:
targets: ~
position: 1
parent: 18
- Expression:
Alias:
name: b
child: 20
- Expression:
Row:
list:
- 19
- 21
distribution:
Segment:
keys:
- positions:
- 0
- Relational:
ScanRelation:
output: 22
id: 18
relation: t2
- Expression:
Reference:
targets:
- 0
position: 1
parent: 24
- Expression:
Alias:
name: b
child: 24
- Expression:
Row:
list:
- 25
distribution: Any
- Relational:
Projection:
children:
- 23
id: 24
output: 26
- Expression:
Reference:
targets:
- 0
position: 0
parent: 28
- Expression:
Alias:
name: b
child: 28
- Expression:
Row:
list:
- 29
distribution: Any
- Relational:
ScanSubQuery:
alias: ~
children:
- 27
id: 28
output: 30
- Expression:
Reference:
targets:
- 1
position: 0
parent: 32
- Expression:
Row:
list:
- 32
distribution:
Segment:
keys:
- positions:
- 0
- Expression:
Reference:
targets:
- 0
position: 0
parent: 32
- Expression:
Row:
list:
- 34
distribution:
Segment:
keys:
- positions:
- 0
- Expression:
Bool:
left: 35
op: Lt
right: 33
- Expression:
Reference:
targets:
- 2
position: 0
parent: 32
- Expression:
Row:
list:
- 37
distribution: Any
- Expression:
Reference:
targets:
- 0
position: 0
parent: 32
- Expression:
Row:
list:
- 39
distribution:
Segment:
keys:
- positions:
- 0
- Expression:
Bool:
left: 40
op: Eq
right: 38
- Expression:
Bool:
left: 36
op: Or
right: 41
- Expression:
Reference:
targets:
- 0
position: 0
parent: 32
- Expression:
Alias:
name: a
child: 43
- Expression:
Row:
list:
- 44
distribution:
Segment:
keys:
- positions:
- 0
- Relational:
Selection:
children:
- 3
- 50
- 54
filter: 42
id: 32
output: 45
- Expression:
Reference:
targets:
- 0
position: 0
parent: 47
- Expression:
Alias:
name: a
child: 47
- Expression:
Row:
list:
- 48
distribution: ~
- Relational:
Motion:
children:
- 17
id: 47
policy: Full
output: 49
- Expression:
Reference:
targets:
- 0
position: 0
parent: 51
- Expression:
Alias:
name: b
child: 51
- Expression:
Row:
list:
- 52
distribution: ~
- Relational:
Motion:
children:
- 31
id: 51
policy:
Segment:
positions:
- 0
output: 53
relations:
t1:
Segment:
columns:
- name: a
type: integer
key:
positions:
- 0
name: t1
t2:
Segment:
columns:
- name: a
type: integer
- name: b
type: integer
key:
positions:
- 0
name: t2
slices: ~
top: 46
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment