Compare commits
2 commits
master
...
fluffyemil
Author | SHA1 | Date | |
---|---|---|---|
|
24a6cce418 | ||
|
7c3f6f3698 |
4 changed files with 86 additions and 6 deletions
|
@ -498,11 +498,11 @@ impl ConjoiningClauses {
|
||||||
match attribute {
|
match attribute {
|
||||||
&PatternNonValuePlace::Ident(ref kw) =>
|
&PatternNonValuePlace::Ident(ref kw) =>
|
||||||
schema.attribute_for_ident(kw)
|
schema.attribute_for_ident(kw)
|
||||||
.when_not(|| self.mark_known_empty(EmptyBecause::InvalidAttributeIdent(kw.clone())))
|
.(|| self.mark_known_empty(EmptyBecause::InvalidAttributeIdent(kw.clone())))
|
||||||
.and_then(|attribute| self.table_for_attribute_and_value(attribute, value)),
|
.and_then(|attribute| self.table_for_attribute_and_value(attribute, value)),
|
||||||
&PatternNonValuePlace::Entid(id) =>
|
&PatternNonValuePlace::Entid(id) =>
|
||||||
schema.attribute_for_entid(id)
|
schema.attribute_for_entid(id)
|
||||||
.when_not(|| self.mark_known_empty(EmptyBecause::InvalidAttributeEntid(id)))
|
.(|| self.mark_known_empty(EmptyBecause::InvalidAttributeEntid(id)))
|
||||||
.and_then(|attribute| self.table_for_attribute_and_value(attribute, value)),
|
.and_then(|attribute| self.table_for_attribute_and_value(attribute, value)),
|
||||||
// TODO: In a prepared context, defer this decision until a second algebrizing phase.
|
// TODO: In a prepared context, defer this decision until a second algebrizing phase.
|
||||||
// #278.
|
// #278.
|
||||||
|
@ -974,6 +974,10 @@ impl ConjoiningClauses {
|
||||||
validate_or_join(&o)
|
validate_or_join(&o)
|
||||||
// TODO: apply.
|
// TODO: apply.
|
||||||
},
|
},
|
||||||
|
WhereClause::NotJoin(n) => {
|
||||||
|
validate_not_join(&n)
|
||||||
|
// TODO: apply.
|
||||||
|
},
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,12 @@ error_chain! {
|
||||||
description("non-matching variables in 'or' clause")
|
description("non-matching variables in 'or' clause")
|
||||||
display("non-matching variables in 'or' clause")
|
display("non-matching variables in 'or' clause")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NonMatchingVariablesInNotClause {
|
||||||
|
// TODO: flesh out.
|
||||||
|
description("non-matching variables in 'not' clause")
|
||||||
|
display("non-matching variables in 'not' clause")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ use std::collections::BTreeSet;
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
ContainsVariables,
|
ContainsVariables,
|
||||||
OrJoin,
|
OrJoin,
|
||||||
|
NotJoin,
|
||||||
Variable,
|
Variable,
|
||||||
WhereClause,
|
WhereClause,
|
||||||
UnifyVars,
|
UnifyVars,
|
||||||
|
@ -75,6 +76,37 @@ pub fn validate_or_join(or_join: &OrJoin) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn validate_not_join(no_join: &NotJoin) -> Result<()> {
|
||||||
|
// Grab our mentioned variables and ensure that the rules are followed.
|
||||||
|
match not_join.unify_vars {
|
||||||
|
UnifyVars::Implicit => {
|
||||||
|
// Each 'leg' must have the same variable set.
|
||||||
|
if not_join.clauses.len() < 2 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
let mut clauses = not_join.clauses.iter();
|
||||||
|
let template = clauses.next().unwrap().collect_mentioned_variables();
|
||||||
|
for clause in clauses {
|
||||||
|
if template != clause.collect_mentioned_variables() {
|
||||||
|
bail!(ErrorKind::NonMatchingVariablesInOrClause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UnifyVars::Explicit(ref vars) => {
|
||||||
|
// Each leg must use the joined vars.
|
||||||
|
let var_set: BTreeSet<Variable> = vars.iter().cloned().collect();
|
||||||
|
for clause in ¬_join.clauses {
|
||||||
|
if !var_set.is_subset(&clause.collect_mentioned_variables()) {
|
||||||
|
bail!(ErrorKind::NonMatchingVariablesInOrClause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
extern crate mentat_core;
|
extern crate mentat_core;
|
||||||
|
@ -93,6 +125,7 @@ mod tests {
|
||||||
UnifyVars,
|
UnifyVars,
|
||||||
Variable,
|
Variable,
|
||||||
WhereClause,
|
WhereClause,
|
||||||
|
WhereNotClause,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::mentat_query_parser::parse_find_string;
|
use self::mentat_query_parser::parse_find_string;
|
||||||
|
|
|
@ -508,6 +508,7 @@ pub enum UnifyVars {
|
||||||
pub enum OrWhereClause {
|
pub enum OrWhereClause {
|
||||||
Clause(WhereClause),
|
Clause(WhereClause),
|
||||||
And(Vec<WhereClause>),
|
And(Vec<WhereClause>),
|
||||||
|
Not(Vec<WhereNotClause>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -516,11 +517,25 @@ pub struct OrJoin {
|
||||||
pub clauses: Vec<OrWhereClause>,
|
pub clauses: Vec<OrWhereClause>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum WhereNotClause {
|
||||||
|
Clause(WhereClause),
|
||||||
|
And(Vec<WhereClause>),
|
||||||
|
Or(Vec<OrWhereClause>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub struct NotJoin {
|
||||||
|
pub unify_vars: UnifyVars,
|
||||||
|
pub clauses: Vec<WhereNotClause>,
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum WhereClause {
|
pub enum WhereClause {
|
||||||
Not,
|
Not(Box<WhereNotClause>),
|
||||||
NotJoin,
|
NotJoin(NotJoin),
|
||||||
|
Or(Box<OrWhereClause>),
|
||||||
OrJoin(OrJoin),
|
OrJoin(OrJoin),
|
||||||
Pred(Predicate),
|
Pred(Predicate),
|
||||||
WhereFn,
|
WhereFn,
|
||||||
|
@ -553,11 +568,12 @@ impl ContainsVariables for WhereClause {
|
||||||
fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
|
fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
|
||||||
use WhereClause::*;
|
use WhereClause::*;
|
||||||
match self {
|
match self {
|
||||||
|
&Or(ref o) => o.accumulate_mentioned_variables(acc),
|
||||||
&OrJoin(ref o) => o.accumulate_mentioned_variables(acc),
|
&OrJoin(ref o) => o.accumulate_mentioned_variables(acc),
|
||||||
&Pred(ref p) => p.accumulate_mentioned_variables(acc),
|
&Pred(ref p) => p.accumulate_mentioned_variables(acc),
|
||||||
&Pattern(ref p) => p.accumulate_mentioned_variables(acc),
|
&Pattern(ref p) => p.accumulate_mentioned_variables(acc),
|
||||||
&Not => (),
|
&Not(ref n) => n.accumulate_mentioned_variables(acc),
|
||||||
&NotJoin => (),
|
&NotJoin(ref n) => n.accumulate_mentioned_variables(acc),
|
||||||
&WhereFn => (),
|
&WhereFn => (),
|
||||||
&RuleExpr => (),
|
&RuleExpr => (),
|
||||||
}
|
}
|
||||||
|
@ -570,6 +586,7 @@ impl ContainsVariables for OrWhereClause {
|
||||||
match self {
|
match self {
|
||||||
&And(ref clauses) => for clause in clauses { clause.accumulate_mentioned_variables(acc) },
|
&And(ref clauses) => for clause in clauses { clause.accumulate_mentioned_variables(acc) },
|
||||||
&Clause(ref clause) => clause.accumulate_mentioned_variables(acc),
|
&Clause(ref clause) => clause.accumulate_mentioned_variables(acc),
|
||||||
|
&Not(ref clauses) => for clause in clauses { clause.accumulate_mentioned_variables(acc) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,6 +599,26 @@ impl ContainsVariables for OrJoin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl ContainsVariables for WhereNotClause {
|
||||||
|
fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
|
||||||
|
use WhereNotClause::*;
|
||||||
|
match self {
|
||||||
|
&And(ref clauses) => for clause in clauses { clause.accumulate_mentioned_variables(acc) },
|
||||||
|
&Clause(ref clause) => clause.accumulate_mentioned_variables(acc),
|
||||||
|
&Or(ref clauses) => for clause in clauses { clause.accumulate_mentioned_variables(acc) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ContainsVariables for NotJoin {
|
||||||
|
fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
|
||||||
|
for clause in &self.clauses {
|
||||||
|
clause.accumulate_mentioned_variables(acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ContainsVariables for Predicate {
|
impl ContainsVariables for Predicate {
|
||||||
fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
|
fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
|
||||||
for arg in &self.args {
|
for arg in &self.args {
|
||||||
|
|
Loading…
Reference in a new issue