Permalink
Browse files

Fixes problem with optional properties and collection predicates (ALL…

…/ANY/NONE/SINGLE/IN)
  • Loading branch information...
1 parent 063c3aa commit 904ac1c7a8f3129393fecef39690de604adb82fd @systay committed Jun 7, 2012
View
@@ -7,6 +7,7 @@ o Fixes #573: Arithmetics operations have wrong type
o Fixes #567: Parameter maps coming through REST are not parsed correctly
o Fixes #563: COUNT(*) does not return 0 for empty result
o Fixes #561: RELATE doesn't work as expected with map-parameters
+o Fixes problem with optional properties and collection predicates (ALL/ANY/NONE/SINGLE/IN)
1.8.M03 (2012-05-24)
--------------------
@@ -49,17 +49,14 @@ trait Predicates extends Base with ParserPattern {
(identity ~ ignoreCase("in") ~ expression ~ ignoreCase("where") ~ predicate ^^ { case symbol ~ in ~ iterable ~ where ~ klas => (iterable, symbol, klas) }
|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-_-")))
+ def in: Parser[Predicate] = expression ~ ignoreCase("in") ~ expression ^^ {
+ 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 anyInSeq: Parser[Predicate] = ignoreCase("any") ~> parens(symbolIterablePredicate) ^^ (x => AnyInIterable(x._1, x._2, x._3))
-
- def noneInSeq: Parser[Predicate] = ignoreCase("none") ~> parens(symbolIterablePredicate) ^^ (x => NoneInIterable(x._1, x._2, x._3))
-
- def singleInSeq: Parser[Predicate] = ignoreCase("single") ~> parens(symbolIterablePredicate) ^^ (x => SingleInIterable(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 => nullable(AnyInIterable(x._1, x._2, x._3), x._1))
+ 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 => 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) } |
@@ -72,14 +69,13 @@ trait Predicates extends Base with ParserPattern {
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 patternPredicate = pathExpression ^^ (NonEmpty(_))
@@ -2008,4 +2008,11 @@ RETURN x0.name?
assertEquals(result.startNode(), a)
assertEquals(result.length(), 2)
}
+
+ @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 904ac1c

Please sign in to comment.