Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Removed the /../ literal for regular expressions. Now a normal string…

… literal is used instead
  • Loading branch information...
commit 2617da162ad457e5b039c61b9484618f40ae4f53 1 parent c3d33ae
Andres Taylor authored
4 cypher/CHANGES.txt
View
@@ -1,3 +1,7 @@
+1.8
+--------------------
+o Removed the /../ literal for regular expressions. Now a normal string literal is used instead
+
1.8.M07 (2012-08-08)
--------------------
o Added escape characters to string literals
4 cypher/src/main/scala/org/neo4j/cypher/internal/parser/v1_8/Predicates.scala
View
@@ -22,7 +22,7 @@ package org.neo4j.cypher.internal.parser.v1_8
import org.neo4j.cypher.internal.commands._
-trait Predicates extends Base with ParserPattern {
+trait Predicates extends Base with ParserPattern with StringLiteral {
def predicate: Parser[Predicate] = predicateLvl1 ~ rep( ignoreCase("or") ~> predicateLvl1 ) ^^ {
case head ~ rest => rest.foldLeft(head)((a,b) => Or(a,b))
}
@@ -66,7 +66,7 @@ trait Predicates extends Base with ParserPattern {
expression ~ ">" ~ expression ^^ { case l ~ ">" ~ r => nullable(GreaterThan(l, r),l,r) } |
expression ~ "<=" ~ expression ^^ { case l ~ "<=" ~ r => nullable(LessThanOrEqual(l, r),l,r) } |
expression ~ ">=" ~ expression ^^ { case l ~ ">=" ~ r => nullable(GreaterThanOrEqual(l, r),l,r) } |
- expression ~ "=~" ~ regularLiteral ^^ { case a ~ "=~" ~ b => nullable(LiteralRegularExpression(a, b),a,b) } |
+ expression ~ "=~" ~ stringLit ^^ { case a ~ "=~" ~ b => nullable(LiteralRegularExpression(a, b),a,b) } |
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 <>"))
8 cypher/src/main/scala/org/neo4j/cypher/internal/parser/v1_8/StringLiteral.scala
View
@@ -19,10 +19,10 @@
*/
package org.neo4j.cypher.internal.parser.v1_8
-import org.neo4j.cypher.internal.commands.{Expression, Literal}
+import org.neo4j.cypher.internal.commands.Literal
trait StringLiteral extends Base {
- def stringLit: Parser[Expression] = Parser {
+ def stringLit: Parser[Literal] = Parser {
case in if in.atEnd => Failure("out of string", in)
case in =>
val start = handleWhiteSpace(in.source, in.offset)
@@ -35,7 +35,7 @@ trait StringLiteral extends Base {
var ls = string.toList.tail
val sb = new StringBuilder(ls.length)
var idx = start
- var result: Option[ParseResult[Expression]] = None
+ var result: Option[ParseResult[Literal]] = None
while (!ls.isEmpty && result.isEmpty) {
val (pref, suf) = ls span {
@@ -77,7 +77,7 @@ trait StringLiteral extends Base {
}
}
- case class EscapeProduct(result: Option[ParseResult[Expression]])
+ case class EscapeProduct(result: Option[ParseResult[Literal]])
private def parseEscapeChars(suf: List[Char], in:Input): Either[Char, Failure] = suf match {
case '\\' :: tail => Left('\\')
19 cypher/src/test/java/org/neo4j/cypher/javacompat/IntroExamplesTest.java
View
@@ -19,25 +19,22 @@
*/
package org.neo4j.cypher.javacompat;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Map;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
-import org.neo4j.test.AsciiDocGenerator;
-import org.neo4j.test.GraphDescription;
+import org.neo4j.test.*;
import org.neo4j.test.GraphDescription.Graph;
-import org.neo4j.test.GraphHolder;
-import org.neo4j.test.ImpermanentGraphDatabase;
-import org.neo4j.test.JavaTestDocsGenerator;
-import org.neo4j.test.TestData;
import org.neo4j.visualization.asciidoc.AsciidocHelper;
-import static org.neo4j.visualization.asciidoc.AsciidocHelper.*;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import static org.neo4j.visualization.asciidoc.AsciidocHelper.createCypherSnippet;
+import static org.neo4j.visualization.asciidoc.AsciidocHelper.createQueryResultSnippet;
public class IntroExamplesTest implements GraphHolder
{
@@ -84,7 +81,7 @@ public void intro_examples() throws Exception
+ data.get().get( "Maria" ).getId()
+ ","
+ data.get().get( "Steve" ).getId()
- + ") MATCH user-[:friend]->follower WHERE follower.name =~ /S.*/ RETURN user, follower.name ";
+ + ") MATCH user-[:friend]->follower WHERE follower.name =~ 'S.*' RETURN user, follower.name ";
fw.append( "\n" );
fw.append( createCypherSnippet( query ) );
fw.append( "\nResulting in\n" );
42 cypher/src/test/scala/org/neo4j/cypher/CypherParserTest.scala
View
@@ -277,8 +277,8 @@ class CypherParserTest extends JUnitSuite with Assertions {
returns(ReturnItem(Entity("a"), "a")))
}
- @Test def shouldHandleRegularComparison() {
- testFrom_1_7(
+ @Test def shouldHandleRegularComparisonOld() {
+ test_1_7(
"start a = node(1) where \"Andres\" =~ /And.*/ return a",
Query.
start(NodeById("a", 1)).
@@ -287,8 +287,18 @@ class CypherParserTest extends JUnitSuite with Assertions {
)
}
- @Test def shouldHandleMultipleRegularComparison1_6() {
- testFrom_1_7(
+ @Test def shouldHandleRegularComparison() {
+ testFrom_1_8(
+ "start a = node(1) where \"Andres\" =~ 'And.*' return a",
+ Query.
+ start(NodeById("a", 1)).
+ where(LiteralRegularExpression(Literal("Andres"), Literal("And.*"))).
+ returns(ReturnItem(Entity("a"), "a"))
+ )
+ }
+
+ @Test def shouldHandleMultipleRegularComparison1_7() {
+ test_1_7(
"""start a = node(1) where a.name =~ /And.*/ AnD a.name =~ /And.*/ return a""",
Query.
start(NodeById("a", 1)).
@@ -298,6 +308,16 @@ class CypherParserTest extends JUnitSuite with Assertions {
}
@Test def shouldHandleMultipleRegularComparison() {
+ testFrom_1_8(
+ """start a = node(1) where a.name =~ 'And.*' AnD a.name =~ 'And.*' return a""",
+ Query.
+ start(NodeById("a", 1)).
+ where(And(LiteralRegularExpression(Property("a", "name"), Literal("And.*")), LiteralRegularExpression(Property("a", "name"), Literal("And.*")))).
+ returns(ReturnItem(Entity("a"), "a"))
+ )
+ }
+
+ @Test def shouldHandleMultipleRegularComparison1_6() {
test_1_6(
"""start a = node(1) where a.name =~ /And.*/ AnD a.name =~ /And.*/ return a""",
Query.
@@ -317,8 +337,8 @@ class CypherParserTest extends JUnitSuite with Assertions {
)
}
- @Test def shouldHandleEscapedRegexs() {
- testFrom_1_7(
+ @Test def shouldHandleEscapedRegexs1_7() {
+ test_1_7(
"""start a = node(1) where a.name =~ /And\/.*/ return a""",
Query.
start(NodeById("a", 1)).
@@ -327,6 +347,16 @@ class CypherParserTest extends JUnitSuite with Assertions {
)
}
+ @Test def shouldHandleEscapedRegexs() {
+ testFrom_1_8(
+ """start a = node(1) where a.name =~ 'And\\/.*' return a""",
+ Query.
+ start(NodeById("a", 1)).
+ where(LiteralRegularExpression(Property("a", "name"), Literal("And\\/.*"))).
+ returns(ReturnItem(Entity("a"), "a"))
+ )
+ }
+
@Test def shouldHandleGreaterThanOrEqual() {
testAll(
"start a = node(1) where a.name >= \"andres\" return a",
17 cypher/src/test/scala/org/neo4j/cypher/ExecutionEngineTest.scala
View
@@ -1214,7 +1214,7 @@ return x, p""")
val result = parseAndExecute( """
start a = node(1)
-where a.name =~ /And.*/ AND a.name =~ /And.*/
+where a.name =~ 'And.*' AND a.name =~ 'And.*'
return a""")
assert(List(a) === result.columnAs[Node]("a").toList)
@@ -1422,7 +1422,7 @@ order by a.COL1
@Test def shouldAllowStringComparisonsInArray() {
val a = createNode("array" -> Array("Cypher duck", "Gremlin orange", "I like the snow"))
- val result = parseAndExecute("start a = node(1) where single(x in a.array where x =~ /.*the.*/) return a")
+ val result = parseAndExecute("start a = node(1) where single(x in a.array where x =~ '.*the.*') return a")
assert(List(Map("a" -> a)) === result.toList)
}
@@ -1642,7 +1642,7 @@ RETURN x0.name?
@Test def shouldHandleAllOperatorsWithNull() {
val a = createNode()
- val result = parseAndExecute("start a=node(1) where a.x? =~ /.*?blah.*?/ and a.x? = 13 and a.x? <> 13 and a.x? > 13 return a")
+ val result = parseAndExecute("start a=node(1) where a.x? =~ '.*?blah.*?' and a.x? = 13 and a.x? <> 13 and a.x? > 13 return a")
assert(List(Map("a" -> a)) === result.toList)
}
@@ -2119,17 +2119,6 @@ RETURN x0.name?
assert(result.toList === List(Map("sum(foo)" -> 8)))
}
- @Test
- def with_should_not_forget_parameters() {
- graph.index().forNodes("test")
- val id = "bar"
- val result = parseAndExecute("start n=node:test(name={id}) with count(*) as c where c=0 create x={name:{id}} return c, x", "id" -> id).toList
-
- assert(result.size === 1)
- assert(result(0)("c").asInstanceOf[Long] === 0)
- assert(result(0)("x").asInstanceOf[Node].getProperty("name") === id)
- }
-
@Ignore("This pattern is currently not supported. Revisit when we do support it.")
@Test
def two_double_optional_paths_with_shared_relationships() {
13 cypher/src/test/scala/org/neo4j/cypher/docgen/WhereTest.scala
View
@@ -55,8 +55,8 @@ class WhereTest extends DocumentingTestBase {
@Test def regular_expressions() {
testQuery(
title = "Regular expressions",
- text = "You can match on regular expressions by using `=~ /regexp/`, like this:",
- queryText = """start n=node(%Andres%, %Tobias%) where n.name =~ /Tob.*/ return n""",
+ text = "You can match on regular expressions by using `=~ \"regexp\"`, like this:",
+ queryText = """start n=node(%Andres%, %Tobias%) where n.name =~ 'Tob.*' return n""",
returns = """The "+Tobias+" node will be returned.""",
assertions = (p) => assertEquals(List(node("Tobias")), p.columnAs[Node]("n").toList))
}
@@ -64,8 +64,9 @@ class WhereTest extends DocumentingTestBase {
@Test def regular_expressions_escaped() {
testQuery(
title = "Escaping in regular expressions",
- text = "If you need a forward slash inside of your regular expression, escape it using a backslash (+\\+).",
- queryText = """start n=node(%Andres%, %Tobias%) where n.name =~ /Some\/thing/ return n""",
+ text = "If you need a forward slash inside of your regular expression, escape it. Remember that back slash needs " +
+ "to be escaped in string literals",
+ queryText = """start n=node(%Andres%, %Tobias%) where n.name =~ 'Some\\/thing' return n""",
returns = """No nodes match this regular expression.""",
assertions = (p) => assertEquals(List(), p.toList))
}
@@ -74,7 +75,7 @@ class WhereTest extends DocumentingTestBase {
testQuery(
title = "Case insensitive regular expressions",
text = "By pre-pending a regular expression with `(?i)`, the whole expression becomes case insensitive.",
- queryText = """start n=node(%Andres%, %Tobias%) where n.name =~ /(?i)ANDR.*/ return n""",
+ queryText = """start n=node(%Andres%, %Tobias%) where n.name =~ '(?i)ANDR.*' return n""",
returns = """The node with name "+Andres+" is returned.""",
assertions = (p) => assertEquals(List(Map("n" -> node("Andres"))), p.toList))
}
@@ -113,7 +114,7 @@ class WhereTest extends DocumentingTestBase {
text = "You can put the exact relationship type in the `MATCH` pattern, but sometimes you want to be able to do more " +
"advanced filtering on the type. You can use the special property `TYPE` to compare the type with something else. " +
"In this example, the query does a regular expression comparison with the name of the relationship type.",
- queryText = """start n=node(%Andres%) match (n)-[r]->() where type(r) =~ /K.*/ return r""",
+ queryText = """start n=node(%Andres%) match (n)-[r]->() where type(r) =~ 'K.*' return r""",
returns = """This returns relationships that has a type whose name starts with K.""",
assertions = (p) => assertEquals("KNOWS", p.columnAs[Relationship]("r").toList.head.getType.name()))
}
Please sign in to comment.
Something went wrong with that request. Please try again.