From 66bcede63eb5d5bfbd3c57bd73e8ae81448bafd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=D5=A1=C4=B1try?= <32328713+dwitry@users.noreply.github.com> Date: Fri, 28 Jun 2019 13:52:23 +0300 Subject: [PATCH] Clarification that `regex` is custom predicate #294 (#296) Signed-off-by: Dwitry dwitry@users.noreply.github.com --- .../gremlin/client/CypherTraversalSourceTest.java | 2 +- tinkerpop/cypher-gremlin-extensions/README.md | 2 ++ .../translation/ir/verify/NoCustomFunctions.scala | 6 +++++- .../ir/verify/NoCustomFunctionsTest.scala | 3 ++- .../translator/TranslatorBuilderTest.scala | 14 +++++++------- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/testware/integration-tests/src/test/java/org/opencypher/gremlin/client/CypherTraversalSourceTest.java b/testware/integration-tests/src/test/java/org/opencypher/gremlin/client/CypherTraversalSourceTest.java index 2bc6a522..5825b5db 100644 --- a/testware/integration-tests/src/test/java/org/opencypher/gremlin/client/CypherTraversalSourceTest.java +++ b/testware/integration-tests/src/test/java/org/opencypher/gremlin/client/CypherTraversalSourceTest.java @@ -123,7 +123,7 @@ public void continueElements() { @Test public void translate() { assertThatThrownBy(() -> g.cypher("RETURN toupper('test')", "cosmosdb")) - .hasMessageContaining("Custom functions and predicates are not supported: cypherToUpper"); + .hasMessageContaining("Custom functions and predicates are not supported on target implementation: cypherToUpper"); } diff --git a/tinkerpop/cypher-gremlin-extensions/README.md b/tinkerpop/cypher-gremlin-extensions/README.md index 868069c3..8831f047 100644 --- a/tinkerpop/cypher-gremlin-extensions/README.md +++ b/tinkerpop/cypher-gremlin-extensions/README.md @@ -49,7 +49,9 @@ If extensions are installed on a target server and translation happens on the cl Functions that are present in Cypher but not in Gremlin: * Type Conversion [functions](https://neo4j.com/docs/cypher-manual/current/functions/scalar/): `toString`, `toBoolean`, `toInteger`, `toFloat` +* Type [predicates](https://github.com/opencypher/cypher-for-gremlin/tree/master/tinkerpop/cypher-gremlin-extensions#queries-that-require-type-information): `isString`, `isRelationship`, `isNode` * [String functions](https://neo4j.com/docs/cypher-manual/current/functions/string/): `reverse`, `substring`, `trim`, `toUpper`, `toLower`... +* [Regex predicate](https://neo4j.com/docs/cypher-manual/current/clauses/where/#query-where-regex): `regex` * Percentile functions: [percentileCont](https://neo4j.com/docs/cypher-manual/current/functions/aggregating/#functions-percentilecont), [percentileDisc](https://neo4j.com/docs/cypher-manual/current/functions/aggregating/#functions-percentiledisc) * [round](https://neo4j.com/docs/cypher-manual/current/functions/mathematical-numeric/#functions-round) function diff --git a/translation/src/main/scala/org/opencypher/gremlin/translation/ir/verify/NoCustomFunctions.scala b/translation/src/main/scala/org/opencypher/gremlin/translation/ir/verify/NoCustomFunctions.scala index 6c1479c7..4efe3373 100644 --- a/translation/src/main/scala/org/opencypher/gremlin/translation/ir/verify/NoCustomFunctions.scala +++ b/translation/src/main/scala/org/opencypher/gremlin/translation/ir/verify/NoCustomFunctions.scala @@ -29,7 +29,10 @@ object NoCustomFunctions extends GremlinPostCondition { })(steps).sorted.distinct if (all.nonEmpty) { - Some(s"Custom functions and predicates are not supported: ${all.mkString(", ")}") + Some( + s"Custom functions and predicates are not supported on target implementation: ${all.mkString(", ")}. " + + "Consider installing Extensions to Gremlin to enable full support for Cypher functionality: " + + "https://github.com/opencypher/cypher-for-gremlin/tree/master/tinkerpop/cypher-gremlin-extensions") } else { None } @@ -50,6 +53,7 @@ object NoCustomFunctions extends GremlinPostCondition { case _: IsNode => Some("cypherIsNode") case _: IsString => Some("cypherIsString") case _: IsRelationship => Some("cypherIsRelationship") + case _: RegexMatch => Some("cypherRegex") case _ => None }) diff --git a/translation/src/test/scala/org/opencypher/gremlin/translation/ir/verify/NoCustomFunctionsTest.scala b/translation/src/test/scala/org/opencypher/gremlin/translation/ir/verify/NoCustomFunctionsTest.scala index b45c7cc3..8db326c7 100644 --- a/translation/src/test/scala/org/opencypher/gremlin/translation/ir/verify/NoCustomFunctionsTest.scala +++ b/translation/src/test/scala/org/opencypher/gremlin/translation/ir/verify/NoCustomFunctionsTest.scala @@ -32,12 +32,13 @@ class NoCustomFunctionsTest { @Test def predicates(): Unit = { val ast = CypherAst.parse("""MATCH (u:User) + |WHERE u.name =~ 'Tim.*' |WITH {key: u} AS nodes |DELETE nodes.key""".stripMargin) val translator = Translator.builder.gremlinGroovy.build(flavor) assertThatThrownBy(() => ast.buildTranslation(translator)) - .hasMessageContaining("cypherIsNode") + .hasMessageContaining("cypherIsNode, cypherRegex") } @Test diff --git a/translation/src/test/scala/org/opencypher/gremlin/translation/translator/TranslatorBuilderTest.scala b/translation/src/test/scala/org/opencypher/gremlin/translation/translator/TranslatorBuilderTest.scala index 165171df..2c885e27 100644 --- a/translation/src/test/scala/org/opencypher/gremlin/translation/translator/TranslatorBuilderTest.scala +++ b/translation/src/test/scala/org/opencypher/gremlin/translation/translator/TranslatorBuilderTest.scala @@ -38,7 +38,7 @@ class TranslatorBuilderTest { () => parse("RETURN toupper('test')") .buildTranslation(dslBuilder)) - .hasMessageContaining("Custom functions and predicates are not supported: cypherToUpper") + .hasMessageContaining("Custom functions and predicates are not supported on target implementation: cypherToUpper") val steps = parse("MATCH (n) RETURN n.name") .buildTranslation(dslBuilder) @@ -77,7 +77,7 @@ class TranslatorBuilderTest { () => parse("RETURN toupper('test')") .buildTranslation(dslBuilder)) - .hasMessageContaining("Custom functions and predicates are not supported: cypherToUpper") + .hasMessageContaining("Custom functions and predicates are not supported on target implementation: cypherToUpper") val steps = parse("MATCH (n) WHERE n.age=$age RETURN count(n)", Map("age" -> 25).asJava) .buildTranslation(dslBuilder) @@ -115,7 +115,7 @@ class TranslatorBuilderTest { () => parse("RETURN toupper('test')") .buildTranslation(dslBuilder)) - .hasMessageContaining("Custom functions and predicates are not supported: cypherToUpper") + .hasMessageContaining("Custom functions and predicates are not supported on target implementation: cypherToUpper") assertThatThrownBy( () => @@ -140,7 +140,7 @@ class TranslatorBuilderTest { () => parse("RETURN toupper('test')") .buildTranslation(dslBuilder)) - .hasMessageContaining("Custom functions and predicates are not supported: cypherToUpper") + .hasMessageContaining("Custom functions and predicates are not supported on target implementation: cypherToUpper") val steps = parse("MATCH (n) RETURN n.name ORDER BY n.name") .buildTranslation(dslBuilder) @@ -160,7 +160,7 @@ class TranslatorBuilderTest { () => parse("RETURN toupper('test')") .buildTranslation(dslBuilder)) - .hasMessageContaining("Custom functions and predicates are not supported: cypherToUpper") + .hasMessageContaining("Custom functions and predicates are not supported on target implementation: cypherToUpper") val steps = parse("MATCH (n) RETURN n.name") .buildTranslation(dslBuilder) @@ -179,7 +179,7 @@ class TranslatorBuilderTest { () => parse("RETURN toupper('test')") .buildTranslation(dslBuilder)) - .hasMessageContaining("Custom functions and predicates are not supported: cypherToUpper") + .hasMessageContaining("Custom functions and predicates are not supported on target implementation: cypherToUpper") val steps = parse("MATCH (n) RETURN n.name") .buildTranslation(dslBuilder) @@ -198,7 +198,7 @@ class TranslatorBuilderTest { () => parse("RETURN toupper('test')") .buildTranslation(dslBuilder)) - .hasMessageContaining("Custom functions and predicates are not supported: cypherToUpper") + .hasMessageContaining("Custom functions and predicates are not supported on target implementation: cypherToUpper") val steps = parse("MATCH (n) RETURN n.name") .buildTranslation(dslBuilder)