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.
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)?),
|
||||
|
||||
@@ -135,7 +135,10 @@ Aggregations: symbols::Aggregation = {
|
||||
//*********************************************************************/
|
||||
// SELECTING / FILTERING DATA */
|
||||
//*********************************************************************/
|
||||
pub Filters = { Bags };
|
||||
pub Filters: symbols::Bag = {
|
||||
<Bags> =>
|
||||
symbols::Bag::ViewPort(Box::new(<>))
|
||||
};
|
||||
|
||||
// All these expressions generate bags.
|
||||
Bags: symbols::Bag = {
|
||||
|
||||
@@ -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(),
|
||||
@@ -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;
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user