Skip to content

Commit

Permalink
Merge pull request #588 from systay/1.7-maint
Browse files Browse the repository at this point in the history
Fixes problem with optional properties and collection predicates
  • Loading branch information
systay committed Jun 7, 2012
2 parents 5b12700 + eb1daf9 commit 882c95f
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
5 changes: 3 additions & 2 deletions cypher/CHANGES.txt
@@ -1,6 +1,7 @@
<NOT YET RELEASED>
----------------
1.7.2 (Not yet released)
------------------------
o Fixes issue #432, #523
o Fixes problem with optional properties and collection predicates

1.7 (2012-04-18)
----------------
Expand Down
Expand Up @@ -185,16 +185,16 @@ trait Expressions extends Base {
|identity ~> ignoreCase("in") ~ expression ~> failure("expected where"))

def in : Parser[Predicate] = expression ~ ignoreCase("in") ~ expression ^^ {
case checkee ~ in ~ collection => AnyInIterable(collection, "-_-INNER-_-", Equals(checkee, Entity("-_-INNER-_-")))
case checkee ~ in ~ collection => nullable(AnyInIterable(collection, "-_-INNER-_-", Equals(checkee, Entity("-_-INNER-_-"))), collection)
}

def allInSeq: Parser[Predicate] = ignoreCase("all") ~> parens(symbolIterablePredicate) ^^ (x => AllInIterable(x._1, x._2, x._3))
def allInSeq: Parser[Predicate] = ignoreCase("all") ~> parens(symbolIterablePredicate) ^^ (x => nullable(AllInIterable(x._1, x._2, x._3), x._1))

def anyInSeq: Parser[Predicate] = ignoreCase("any") ~> parens(symbolIterablePredicate) ^^ (x => AnyInIterable(x._1, x._2, x._3))
def anyInSeq: Parser[Predicate] = ignoreCase("any") ~> parens(symbolIterablePredicate) ^^ (x => nullable(AnyInIterable(x._1, x._2, x._3), x._1))

def noneInSeq: Parser[Predicate] = ignoreCase("none") ~> parens(symbolIterablePredicate) ^^ (x => NoneInIterable(x._1, x._2, x._3))
def noneInSeq: Parser[Predicate] = ignoreCase("none") ~> parens(symbolIterablePredicate) ^^ (x => nullable(NoneInIterable(x._1, x._2, x._3), x._1))

def singleInSeq: Parser[Predicate] = ignoreCase("single") ~> parens(symbolIterablePredicate) ^^ (x => SingleInIterable(x._1, x._2, x._3))
def singleInSeq: Parser[Predicate] = ignoreCase("single") ~> parens(symbolIterablePredicate) ^^ (x => nullable(SingleInIterable(x._1, x._2, x._3), x._1))

def operators:Parser[Predicate] =
(expression ~ "=" ~ expression ^^ { case l ~ "=" ~ r => nullable(Equals(l, r),l,r) } |
Expand All @@ -207,14 +207,13 @@ trait Expressions extends Base {
expression ~ "=~" ~ expression ^^ { case a ~ "=~" ~ b => nullable(RegularExpression(a, b),a,b) } |
expression ~> "!" ~> failure("The exclamation symbol is used as a nullable property operator in Cypher. The 'not equal to' operator is <>"))

private def nullable(pred:Predicate, e:Expression*):Predicate = if(!e.exists(_.isInstanceOf[Nullable]))
private def nullable(pred: Predicate, e: Expression*): Predicate = if (!e.exists(_.isInstanceOf[Nullable]))
pred
else
{
else {
val map = e.filter(x => x.isInstanceOf[Nullable]).
map( x => (x, x.isInstanceOf[DefaultTrue]))
map(x => (x, x.isInstanceOf[DefaultTrue]))

NullablePredicate(pred, map )
NullablePredicate(pred, map)
}

def expressionOrEntity = expression | entity
Expand Down
Expand Up @@ -1866,4 +1866,10 @@ RETURN x0.name?
assert(parseAndExecute(q).toList === List(Map("x"->null)))
}

@Test
def in_against_non_existing_collection() {
val result = parseAndExecute("start a=node(0) where 'z' in a.array_prop? return a")
assert(result.toList === List(Map("a" -> refNode)))
}

}

0 comments on commit 882c95f

Please sign in to comment.