Part 1 - Parse not
and not-join
This commit is contained in:
parent
4b45827be7
commit
76d0223c2a
2 changed files with 151 additions and 15 deletions
|
@ -43,6 +43,8 @@ use self::mentat_query::{
|
||||||
FromValue,
|
FromValue,
|
||||||
OrJoin,
|
OrJoin,
|
||||||
OrWhereClause,
|
OrWhereClause,
|
||||||
|
NotJoin,
|
||||||
|
WhereNotClause,
|
||||||
Pattern,
|
Pattern,
|
||||||
PatternNonValuePlace,
|
PatternNonValuePlace,
|
||||||
PatternValuePlace,
|
PatternValuePlace,
|
||||||
|
@ -163,6 +165,10 @@ def_parser!(Where, or_join, edn::ValueAndSpan, {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
def_matches_plain_symbol!(Where, or_join, "not");
|
||||||
|
|
||||||
|
def_matches_plain_symbol!(Where, or_join, "not-join");
|
||||||
|
|
||||||
def_parser!(Where, rule_vars, Vec<Variable>, {
|
def_parser!(Where, rule_vars, Vec<Variable>, {
|
||||||
seq()
|
seq()
|
||||||
.of_exactly(many1(Query::variable()))
|
.of_exactly(many1(Query::variable()))
|
||||||
|
@ -210,6 +216,53 @@ def_parser!(Where, or_join_clause, WhereClause, {
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
def_value_parser_fn!(Where, not_pattern_clause, WhereNotClause, input, {
|
||||||
|
Where::clause().map(|clause| WhereNotClause::Clause(clause)).parse_stream(input)
|
||||||
|
});
|
||||||
|
|
||||||
|
def_value_parser_fn!(Where, where_not_clause, WhereNotClause, input, {
|
||||||
|
choice([Where::not_pattern_clause()]).parse_stream(input)
|
||||||
|
});
|
||||||
|
|
||||||
|
def_value_parser_fn!(Where, not_clause, WhereClause, input, {
|
||||||
|
satisfy_map(|x: edn::Value| {
|
||||||
|
seq(x).and_then(|items| {
|
||||||
|
let mut p = Where::not()
|
||||||
|
.with(many1(Where::where_not_clause()))
|
||||||
|
.skip(eof())
|
||||||
|
.map(|clauses| {
|
||||||
|
WhereClause::NotJoin(
|
||||||
|
NotJoin {
|
||||||
|
unify_vars: UnifyVars::Implicit,
|
||||||
|
clauses: clauses,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
let r: ParseResult<WhereClause, _> = p.parse_lazy(&items[..]).into();
|
||||||
|
Query::to_parsed_value(r)
|
||||||
|
})
|
||||||
|
}).parse_stream(input)
|
||||||
|
});
|
||||||
|
|
||||||
|
def_value_parser_fn!(Where, not_join_clause, WhereClause, input, {
|
||||||
|
satisfy_map(|x: edn::Value| {
|
||||||
|
seq(x).and_then(|items| {
|
||||||
|
let mut p = Where::not_join()
|
||||||
|
.with(Where::rule_vars())
|
||||||
|
.and(many1(Where::where_not_clause()))
|
||||||
|
.skip(eof())
|
||||||
|
.map(|(vars, clauses)| {
|
||||||
|
WhereClause::NotJoin(
|
||||||
|
NotJoin {
|
||||||
|
unify_vars: UnifyVars::Explicit(vars),
|
||||||
|
clauses: clauses,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
let r: ParseResult<WhereClause, _> = p.parse_lazy(&items[..]).into();
|
||||||
|
Query::to_parsed_value(r)
|
||||||
|
})
|
||||||
|
}).parse_stream(input)
|
||||||
|
});
|
||||||
|
|
||||||
/// A vector containing just a parenthesized filter expression.
|
/// A vector containing just a parenthesized filter expression.
|
||||||
def_parser!(Where, pred, WhereClause, {
|
def_parser!(Where, pred, WhereClause, {
|
||||||
// Accept either a nested list or a nested vector here:
|
// Accept either a nested list or a nested vector here:
|
||||||
|
@ -293,6 +346,8 @@ def_parser!(Where, clause, WhereClause, {
|
||||||
// We don't yet handle source vars.
|
// We don't yet handle source vars.
|
||||||
try(Where::or_join_clause()),
|
try(Where::or_join_clause()),
|
||||||
try(Where::or_clause()),
|
try(Where::or_clause()),
|
||||||
|
try(Where::not_join_clause()),
|
||||||
|
try(Where::not_clause()),
|
||||||
|
|
||||||
try(Where::pred()),
|
try(Where::pred()),
|
||||||
try(Where::where_fn()),
|
try(Where::where_fn()),
|
||||||
|
@ -641,6 +696,59 @@ mod test {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_not() {
|
||||||
|
let oj = edn::PlainSymbol::new("not");
|
||||||
|
let e = edn::PlainSymbol::new("?e");
|
||||||
|
let a = edn::PlainSymbol::new("?a");
|
||||||
|
let v = edn::PlainSymbol::new("?v");
|
||||||
|
let input = [edn::Value::List(
|
||||||
|
vec![edn::Value::PlainSymbol(oj),
|
||||||
|
edn::Value::Vector(vec![edn::Value::PlainSymbol(e.clone()),
|
||||||
|
edn::Value::PlainSymbol(a.clone()),
|
||||||
|
edn::Value::PlainSymbol(v.clone())])].into_iter().collect())];
|
||||||
|
assert_parses_to!(Where::not_clause, input,
|
||||||
|
WhereClause::NotJoin(
|
||||||
|
NotJoin {
|
||||||
|
unify_vars: UnifyVars::Implicit,
|
||||||
|
clauses: vec![WhereNotClause::Clause(
|
||||||
|
WhereClause::Pattern(Pattern {
|
||||||
|
source: None,
|
||||||
|
entity: PatternNonValuePlace::Variable(variable(e)),
|
||||||
|
attribute: PatternNonValuePlace::Variable(variable(a)),
|
||||||
|
value: PatternValuePlace::Variable(variable(v)),
|
||||||
|
tx: PatternNonValuePlace::Placeholder,
|
||||||
|
}))],
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_not_join() {
|
||||||
|
let oj = edn::PlainSymbol::new("not-join");
|
||||||
|
let e = edn::PlainSymbol::new("?e");
|
||||||
|
let a = edn::PlainSymbol::new("?a");
|
||||||
|
let v = edn::PlainSymbol::new("?v");
|
||||||
|
let input = [edn::Value::List(
|
||||||
|
vec![edn::Value::PlainSymbol(oj),
|
||||||
|
edn::Value::Vector(vec![edn::Value::PlainSymbol(e.clone())]),
|
||||||
|
edn::Value::Vector(vec![edn::Value::PlainSymbol(e.clone()),
|
||||||
|
edn::Value::PlainSymbol(a.clone()),
|
||||||
|
edn::Value::PlainSymbol(v.clone())])].into_iter().collect())];
|
||||||
|
assert_parses_to!(Where::not_join_clause, input,
|
||||||
|
WhereClause::NotJoin(
|
||||||
|
NotJoin {
|
||||||
|
unify_vars: UnifyVars::Explicit(vec![variable(e.clone())]),
|
||||||
|
clauses: vec![WhereNotClause::Clause(
|
||||||
|
WhereClause::Pattern(Pattern {
|
||||||
|
source: None,
|
||||||
|
entity: PatternNonValuePlace::Variable(variable(e)),
|
||||||
|
attribute: PatternNonValuePlace::Variable(variable(a)),
|
||||||
|
value: PatternValuePlace::Variable(variable(v)),
|
||||||
|
tx: PatternNonValuePlace::Placeholder,
|
||||||
|
}))],
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_find_sp_variable() {
|
fn test_find_sp_variable() {
|
||||||
let sym = edn::PlainSymbol::new("?x");
|
let sym = edn::PlainSymbol::new("?x");
|
||||||
|
|
|
@ -189,18 +189,6 @@ pub enum FnArg {
|
||||||
|
|
||||||
impl FromValue<FnArg> for FnArg {
|
impl FromValue<FnArg> for FnArg {
|
||||||
fn from_value(v: edn::ValueAndSpan) -> Option<FnArg> {
|
fn from_value(v: edn::ValueAndSpan) -> Option<FnArg> {
|
||||||
<<<<<<< HEAD
|
|
||||||
// TODO: support SrcVars.
|
|
||||||
Variable::from_value(v.clone()) // TODO: don't clone!
|
|
||||||
.and_then(|v| Some(FnArg::Variable(v)))
|
|
||||||
.or_else(|| {
|
|
||||||
println!("from_value {}", v.inner);
|
|
||||||
match v.inner {
|
|
||||||
edn::SpannedValue::Integer(i) => Some(FnArg::EntidOrInteger(i)),
|
|
||||||
edn::SpannedValue::Float(f) => Some(FnArg::Constant(NonIntegerConstant::Float(f))),
|
|
||||||
_ => unimplemented!(),
|
|
||||||
}})
|
|
||||||
=======
|
|
||||||
use edn::SpannedValue::*;
|
use edn::SpannedValue::*;
|
||||||
match v.inner {
|
match v.inner {
|
||||||
Integer(x) =>
|
Integer(x) =>
|
||||||
|
@ -229,7 +217,6 @@ impl FromValue<FnArg> for FnArg {
|
||||||
Set(_) |
|
Set(_) |
|
||||||
Map(_) => None,
|
Map(_) => None,
|
||||||
}
|
}
|
||||||
>>>>>>> 71d3aa29ed3b383f030e9b3d13eeef5a12820be1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,11 +618,30 @@ pub struct OrJoin {
|
||||||
pub clauses: Vec<OrWhereClause>,
|
pub clauses: Vec<OrWhereClause>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum WhereNotClause {
|
||||||
|
Clause(WhereClause),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WhereNotClause {
|
||||||
|
pub fn is_pattern_or_patterns(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
&WhereNotClause::Clause(WhereClause::Pattern(_)) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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,
|
NotJoin(NotJoin),
|
||||||
NotJoin,
|
|
||||||
OrJoin(OrJoin),
|
OrJoin(OrJoin),
|
||||||
Pred(Predicate),
|
Pred(Predicate),
|
||||||
WhereFn(WhereFn),
|
WhereFn(WhereFn),
|
||||||
|
@ -689,9 +695,14 @@ impl ContainsVariables for WhereClause {
|
||||||
&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),
|
||||||
|
<<<<<<< HEAD
|
||||||
&Not => (),
|
&Not => (),
|
||||||
&NotJoin => (),
|
&NotJoin => (),
|
||||||
&WhereFn(_) => (),
|
&WhereFn(_) => (),
|
||||||
|
=======
|
||||||
|
&NotJoin(ref n) => n.accumulate_mentioned_variables(acc),
|
||||||
|
&WhereFn => (),
|
||||||
|
>>>>>>> Part 1 - Parse `not` and `not-join`
|
||||||
&RuleExpr => (),
|
&RuleExpr => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -715,6 +726,23 @@ impl ContainsVariables for OrJoin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 WhereNotClause {
|
||||||
|
fn accumulate_mentioned_variables(&self, acc: &mut BTreeSet<Variable>) {
|
||||||
|
use WhereNotClause::*;
|
||||||
|
match self {
|
||||||
|
&Clause(ref clause) => 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