Compare commits

...

3 Commits

Author SHA1 Message Date
8dd9250dbb Maybe do not wrap at the top-level 2019-10-18 12:27:30 +02:00
661abbc9f4 Add a new symbol, ViewPort
This is used to wrap the filters within an implicit bounding box,
which corresponds to the view port optionally provided by the users.

The intersection is automatically computed between the query results
and the ViewPort, whenever it is specified.
2019-10-18 12:27:30 +02:00
927feb0297 Actually use the smallest value possible 2019-10-18 12:27:30 +02:00
6 changed files with 38 additions and 3 deletions

View File

@@ -40,6 +40,18 @@ fn complement_helper(
}
}
fn view_port(core_id: &str, parameters: &CoreQueryParameters, bag: &Bag) -> mercator_db::ResultSet {
if let Some((low, high)) = parameters.view_port {
let vp = Bag::Inside(Shape::HyperRectangle(
bag.space().clone(),
vec![low.into(), high.into()],
));
intersection(core_id, parameters, &vp, bag)
} else {
bag.execute(core_id, parameters)
}
}
fn distinct(core_id: &str, parameters: &CoreQueryParameters, bag: &Bag) -> mercator_db::ResultSet {
match bag.execute(core_id, parameters) {
e @ Err(_) => e,
@@ -282,6 +294,7 @@ impl Executor for Bag {
let core = parameters.db.core(core_id)?;
match self {
Bag::ViewPort(bag) => view_port(core_id, parameters, bag),
Bag::Distinct(bag) => distinct(core_id, parameters, bag),
Bag::Filter(predicate, bag) => filter(core_id, parameters, predicate, bag),
Bag::Complement(bag) => complement(core_id, parameters, core, bag),

View File

@@ -31,6 +31,7 @@ fn main() {
db: &db,
output_space: None,
threshold_volume: None,
view_port: &None,
resolution: None,
};
let parser = QueryParser::new();
@@ -51,7 +52,7 @@ fn main() {
}
info_time!("Interpretation");
let mut parse;
let parse;
{
info_time!("Parsing");
parse = parser.parse(&input);

View File

@@ -15,6 +15,7 @@ impl Predictor for Projection {
impl Predictor for Bag {
fn predict(&self, db: &DataBase) -> Result<f64, String> {
match self {
Bag::ViewPort(bag) => bag.predict(db),
Bag::Distinct(bag) => bag.predict(db),
Bag::Filter(_, bag) => bag.predict(db),
Bag::Complement(bag) => Ok(db.space(bag.space())?.volume() - bag.predict(db)?),

View File

@@ -135,7 +135,11 @@ Aggregations: symbols::Aggregation = {
//*********************************************************************/
// SELECTING / FILTERING DATA */
//*********************************************************************/
pub Filters = { Bags };
pub Filters: symbols::Bag = {
<Bags>
//<Bags> =>
// symbols::Bag::ViewPort(Box::new(<>))
};
// All these expressions generate bags.
Bags: symbols::Bag = {

View File

@@ -57,6 +57,9 @@ struct Transform {
/**********************************************************************/
#[derive(Clone, Debug)]
pub enum Bag {
// This is an implicit operator, inserted by the parser. Never to be used directly.
ViewPort(Box<Bag>),
// Bags
Distinct(Box<Bag>),
Filter(Option<Predicate>, Box<Bag>),
Complement(Box<Bag>),
@@ -72,6 +75,7 @@ pub enum Bag {
impl Bag {
pub fn space(&self) -> &String {
match self {
Bag::ViewPort(bag) => bag.space(),
Bag::Distinct(bag) => bag.space(),
Bag::Filter(_, bag) => bag.space(),
Bag::Complement(bag) => bag.space(),
@@ -135,7 +139,7 @@ impl Shape {
pub fn volume(&self) -> f64 {
match self {
Shape::Point(_, _) => 1.0, // This is the smallest non-zero volume possible //TODO DOUBLE CHECK IT IS TRUE
Shape::Point(_, _) => std::f64::EPSILON, // The smallest non-zero volume possible
Shape::HyperRectangle(_space, pos) => {
//TODO: At this time, only aligned to the axes, defined by two points, hyperrectangles are supported.
assert_eq!(pos.len(), 2);
@@ -333,6 +337,17 @@ impl From<&LiteralPosition> for Vec<f64> {
}
}
impl From<&Vec<f64>> for LiteralPosition {
fn from(v: &Vec<f64>) -> Self {
let mut lv = Vec::with_capacity(v.len());
for value in v {
lv.push(LiteralNumber::Float(*value));
}
LiteralPosition(lv)
}
}
impl PartialOrd for LiteralPosition {
fn partial_cmp(&self, other: &LiteralPosition) -> Option<Ordering> {
let LiteralPosition(lh) = self;

View File

@@ -54,6 +54,7 @@ impl Validator for Bag {
}
match self {
Bag::ViewPort(bag) => bag.validate(),
Bag::Distinct(bag) => bag.validate(),
Bag::Filter(_, bag) => bag.validate(),
Bag::Complement(bag) => bag.validate(),