Set the volume in the parser for Filters

When no volume is provided, create by default a volume containing the
whole space.

This simplifies handling later on, as there is no checks and on-the-fly
generation of that value necessary. This also remove life time issues as
the volume is always present with the same life time as the rest of the
Filter.
This commit is contained in:
2020-07-25 08:49:36 +02:00
parent e4cbdf836f
commit 69fbc9fdd8
4 changed files with 21 additions and 19 deletions

View File

@@ -1,4 +1,3 @@
use mercator_db::space;
use mercator_db::DataBase; use mercator_db::DataBase;
use super::expressions::Predictor; use super::expressions::Predictor;
@@ -18,10 +17,7 @@ impl Predictor for Bag {
match self { match self {
Bag::ViewPort(bag) => bag.predict(db), Bag::ViewPort(bag) => bag.predict(db),
Bag::Distinct(bag) => bag.predict(db), Bag::Distinct(bag) => bag.predict(db),
Bag::Filter(_, bag) => match bag { Bag::Filter(_, bag) => bag.predict(db),
None => Ok(db.space(space::Space::universe().name())?.volume()),
Some(b) => b.predict(db),
},
Bag::Complement(bag) => Ok(db.space(bag.space())?.volume() - bag.predict(db)?), Bag::Complement(bag) => Ok(db.space(bag.space())?.volume() - bag.predict(db)?),
Bag::Intersection(lh, rh) => { Bag::Intersection(lh, rh) => {
let l = lh.predict(db)?; let l = lh.predict(db)?;

View File

@@ -189,13 +189,25 @@ Union: symbols::Bag = {
Filter: symbols::Bag = { Filter: symbols::Bag = {
// "filter" "(" <p:Predicates> "," <b:Bags> ")" => // "filter" "(" <p:Predicates> "," <b:Bags> ")" =>
"filter" "(" <b:Bags> ")" => "filter" "(" <b:Bags> ")" =>
symbols::Bag::Filter(None, Some(Box::new(b))), symbols::Bag::Filter(None, Box::new(b)),
"filter" "(" <p:Predicates> <b:("," <Bags> )?> ")" => "filter" "(" <p:Predicates> <b:("," <Bags> )?> ")" => {
match b { match b {
None => symbols::Bag::Filter(Some(p), None), None => {
Some(b) => symbols::Bag::Filter(Some(p), Some(Box::new(b))), let (low, high) = Space::universe().bounding_box();
let low: Vec<_> = low.into();
let high: Vec<_> = high.into();
let shape = symbols::Shape::HyperRectangle(
Space::universe().name().clone(),
vec![
symbols::LiteralPosition(low.into_iter().map(symbols::LiteralNumber::Float).collect()),
symbols::LiteralPosition(high.into_iter().map(symbols::LiteralNumber::Float).collect()),
],
);
symbols::Bag::Filter(Some(p), Box::new(symbols::Bag::Inside(shape)))
}
Some(b) => symbols::Bag::Filter(Some(p), Box::new(b)),
} }
},
}; };
Predicates: symbols::Predicate = { Predicates: symbols::Predicate = {

View File

@@ -61,7 +61,7 @@ pub enum Bag {
ViewPort(Box<Bag>), ViewPort(Box<Bag>),
// Bags // Bags
Distinct(Box<Bag>), Distinct(Box<Bag>),
Filter(Option<Predicate>, Option<Box<Bag>>), Filter(Option<Predicate>, Box<Bag>),
Complement(Box<Bag>), Complement(Box<Bag>),
Intersection(Box<Bag>, Box<Bag>), Intersection(Box<Bag>, Box<Bag>),
Union(Box<Bag>, Box<Bag>), Union(Box<Bag>, Box<Bag>),
@@ -77,10 +77,7 @@ impl Bag {
match self { match self {
Bag::ViewPort(bag) => bag.space(), Bag::ViewPort(bag) => bag.space(),
Bag::Distinct(bag) => bag.space(), Bag::Distinct(bag) => bag.space(),
Bag::Filter(_, bag) => match bag { Bag::Filter(_, bag) => bag.space(),
None => space::Space::universe().name(),
Some(b) => b.space(),
},
Bag::Complement(bag) => bag.space(), Bag::Complement(bag) => bag.space(),
Bag::Intersection(lh, _) => { Bag::Intersection(lh, _) => {
// We are assuming lh and rh are in the same space. // We are assuming lh and rh are in the same space.

View File

@@ -56,10 +56,7 @@ impl Validator for Bag {
match self { match self {
Bag::ViewPort(bag) => bag.validate(), Bag::ViewPort(bag) => bag.validate(),
Bag::Distinct(bag) => bag.validate(), Bag::Distinct(bag) => bag.validate(),
Bag::Filter(_, bag) => match bag { Bag::Filter(_, bag) => bag.validate(),
None => Ok(LiteralPosition(vec![]).get_type()),
Some(b) => b.validate(),
},
Bag::Complement(bag) => bag.validate(), Bag::Complement(bag) => bag.validate(),
Bag::Intersection(lh, rh) => compare_bag_types(lh, rh), Bag::Intersection(lh, rh) => compare_bag_types(lh, rh),
Bag::Union(lh, rh) => compare_bag_types(lh, rh), Bag::Union(lh, rh) => compare_bag_types(lh, rh),