Uses the same key space inside and outside of aggregate evaluation

There is a project node just alongside aggregates so the key space is already bounded by it
pull/273/head
Tpt 2 years ago committed by Thomas Tanon
parent 00ab9ab83c
commit 865f1dac8d
  1. 20
      lib/src/sparql/eval.rs
  2. 8
      lib/src/sparql/plan.rs
  3. 33
      lib/src/sparql/plan_builder.rs

@ -561,11 +561,11 @@ impl SimpleEvaluator {
} }
PlanNode::Aggregate { PlanNode::Aggregate {
child, child,
key_mapping, key_variables,
aggregates, aggregates,
} => { } => {
let child = self.plan_evaluator(child); let child = self.plan_evaluator(child);
let key_mapping = key_mapping.clone(); let key_variables = key_variables.clone();
let aggregate_input_expressions: Vec<_> = aggregates let aggregate_input_expressions: Vec<_> = aggregates
.iter() .iter()
.map(|(aggregate, _)| { .map(|(aggregate, _)| {
@ -588,8 +588,8 @@ impl SimpleEvaluator {
let accumulator_variables: Vec<_> = let accumulator_variables: Vec<_> =
aggregates.iter().map(|(_, var)| *var).collect(); aggregates.iter().map(|(_, var)| *var).collect();
Rc::new(move |from| { Rc::new(move |from| {
let tuple_size = from.capacity(); //TODO: not nice let tuple_size = from.capacity();
let key_mapping = key_mapping.clone(); let key_variables = key_variables.clone();
let mut errors = Vec::default(); let mut errors = Vec::default();
let mut accumulators_for_group = let mut accumulators_for_group =
HashMap::<Vec<Option<EncodedTerm>>, Vec<Box<dyn Accumulator>>>::default(); HashMap::<Vec<Option<EncodedTerm>>, Vec<Box<dyn Accumulator>>>::default();
@ -603,9 +603,9 @@ impl SimpleEvaluator {
}) })
.for_each(|tuple| { .for_each(|tuple| {
//TODO avoid copy for key? //TODO avoid copy for key?
let key = key_mapping let key = key_variables
.iter() .iter()
.map(|(v, _)| tuple.get(*v).cloned()) .map(|v| tuple.get(*v).cloned())
.collect(); .collect();
let key_accumulators = let key_accumulators =
@ -623,7 +623,7 @@ impl SimpleEvaluator {
); );
} }
}); });
if accumulators_for_group.is_empty() && key_mapping.is_empty() { if accumulators_for_group.is_empty() && key_variables.is_empty() {
// There is always a single group if there is no GROUP BY // There is always a single group if there is no GROUP BY
accumulators_for_group.insert(Vec::new(), Vec::new()); accumulators_for_group.insert(Vec::new(), Vec::new());
} }
@ -635,9 +635,9 @@ impl SimpleEvaluator {
.chain(accumulators_for_group.into_iter().map( .chain(accumulators_for_group.into_iter().map(
move |(key, accumulators)| { move |(key, accumulators)| {
let mut result = EncodedTuple::with_capacity(tuple_size); let mut result = EncodedTuple::with_capacity(tuple_size);
for (from_position, to_position) in key_mapping.iter() { for (variable, value) in key_variables.iter().zip(key) {
if let Some(value) = &key[*from_position] { if let Some(value) = value {
result.set(*to_position, value.clone()); result.set(*variable, value);
} }
} }
for (accumulator, variable) in for (accumulator, variable) in

@ -90,7 +90,7 @@ pub enum PlanNode {
Aggregate { Aggregate {
// By definition the group by key are the range 0..key_mapping.len() // By definition the group by key are the range 0..key_mapping.len()
child: Box<Self>, child: Box<Self>,
key_mapping: Rc<Vec<(usize, usize)>>, // aggregate key pairs of (variable key in child, variable key in output) key_variables: Rc<Vec<usize>>,
aggregates: Rc<Vec<(PlanAggregation, usize)>>, aggregates: Rc<Vec<(PlanAggregation, usize)>>,
}, },
} }
@ -200,12 +200,12 @@ impl PlanNode {
} }
} }
Self::Aggregate { Self::Aggregate {
key_mapping, key_variables,
aggregates, aggregates,
.. ..
} => { } => {
for (_, o) in key_mapping.iter() { for var in key_variables.iter() {
callback(*o); callback(*var);
} }
for (_, var) in aggregates.iter() { for (_, var) in aggregates.iter() {
callback(*var); callback(*var);

@ -179,40 +179,21 @@ impl<'a> PlanBuilder<'a> {
inner, inner,
variables: by, variables: by,
aggregates, aggregates,
} => { } => PlanNode::Aggregate {
let mut inner_variables = by.clone(); child: Box::new(self.build_for_graph_pattern(inner, variables, graph_name)?),
let inner_graph_name = key_variables: Rc::new(by.iter().map(|k| variable_key(variables, k)).collect()),
Self::convert_pattern_value_id(graph_name, variables, &mut inner_variables);
PlanNode::Aggregate {
child: Box::new(self.build_for_graph_pattern(
inner,
&mut inner_variables,
&inner_graph_name,
)?),
key_mapping: Rc::new(
by.iter()
.map(|k| {
(
variable_key(&mut inner_variables, k),
variable_key(variables, k),
)
})
.collect(),
),
aggregates: Rc::new( aggregates: Rc::new(
aggregates aggregates
.iter() .iter()
.map(|(v, a)| { .map(|(v, a)| {
Ok(( Ok((
self.build_for_aggregate(a, &mut inner_variables, graph_name)?, self.build_for_aggregate(a, variables, graph_name)?,
variable_key(variables, v), variable_key(variables, v),
)) ))
}) })
.collect::<Result<Vec<_>, EvaluationError>>()?, .collect::<Result<Vec<_>, EvaluationError>>()?,
), ),
} },
}
GraphPattern::Values { GraphPattern::Values {
variables: table_variables, variables: table_variables,
bindings, bindings,
@ -1136,11 +1117,11 @@ impl<'a> PlanBuilder<'a> {
} }
} }
PlanNode::Aggregate { PlanNode::Aggregate {
key_mapping, key_variables,
aggregates, aggregates,
.. ..
} => { } => {
set.extend(key_mapping.iter().map(|(_, o)| o)); set.extend(key_variables.iter());
//TODO: This is too harsh //TODO: This is too harsh
for (_, var) in aggregates.iter() { for (_, var) in aggregates.iter() {
set.insert(*var); set.insert(*var);

Loading…
Cancel
Save