This is an automated email from the ASF dual-hosted git repository.

felixcheung pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git


The following commit(s) were added to refs/heads/master by this push:
     new 9a185f1  [ZEPPELIN-3882] Neo4jInterpreter - Support Point and Date 
Types (#3284)
9a185f1 is described below

commit 9a185f19124259f0d510a3669d1023065bdf6197
Author: Andrea Santurbano <sant...@gmail.com>
AuthorDate: Mon Jan 21 20:51:01 2019 +0100

    [ZEPPELIN-3882] Neo4jInterpreter - Support Point and Date Types (#3284)
    
    ### What is this PR for?
    Add the support for Point and Date data types introduced since Neo4j 3.4
    
    ### What type of PR is it?
    [Improvement] In order to allow users to use the Neo4j Interpreter with the 
last introduced Data types
    
    ### Todos
    * [x] - Bumped Neo4j dependecies version
    * [x] - Added new data types to test
    
    ### What is the Jira issue?
    * Put link here, and add 
[ZEPPELIN-3882](https://issues.apache.org/jira/projects/ZEPPELIN/issues/ZEPPELIN-3882)
    
    ### How should this be tested?
    * Execute the unit tests
    
    ### Screenshots (if appropriate)
    
    ### Questions:
    * Does the licenses files need update? no
    * Is there breaking changes for older versions? no
    * Does this needs documentation? no
    
    
    * Added support for Neo4j temporal and point types
    
    * fix checkstyle
---
 docs/interpreter/neo4j.md                          |   3 +
 neo4j/pom.xml                                      |   6 +-
 .../graph/neo4j/Neo4jCypherInterpreter.java        |  14 +++
 .../graph/neo4j/Neo4jCypherInterpreterTest.java    | 105 +++++++++++++++++----
 4 files changed, 108 insertions(+), 20 deletions(-)

diff --git a/docs/interpreter/neo4j.md b/docs/interpreter/neo4j.md
index 1b14127..eec9e07 100644
--- a/docs/interpreter/neo4j.md
+++ b/docs/interpreter/neo4j.md
@@ -26,6 +26,9 @@ limitations under the License.
 ## Overview
 [Neo4j](https://neo4j.com/product/) is a native graph database, designed to 
store and process graphs from bottom to top.
 
+### Supported Version
+
+The Neo4j Interpreter supports all Neo4j versions since v3 via the official 
[Neo4j Java Driver](https://github.com/neo4j/neo4j-java-driver)
 
 ![Neo4j - Interpreter - 
Video]({{BASE_PATH}}/assets/themes/zeppelin/img/docs-img/neo4j-interpreter-video.gif)
 
diff --git a/neo4j/pom.xml b/neo4j/pom.xml
index b8a89ad..cc39fdc 100644
--- a/neo4j/pom.xml
+++ b/neo4j/pom.xml
@@ -33,9 +33,9 @@
   <name>Zeppelin: Neo4j interpreter</name>
   
   <properties>
-       <neo4j.driver.version>1.4.3</neo4j.driver.version>
-       <test.neo4j.kernel.version>3.2.3</test.neo4j.kernel.version>
-       <neo4j.version>3.2.3</neo4j.version>
+       <neo4j.driver.version>1.7.1</neo4j.driver.version>
+       <test.neo4j.kernel.version>3.4.10</test.neo4j.kernel.version>
+       <neo4j.version>3.4.10</neo4j.version>
        <jackson.version>2.8.9</jackson.version>
     <interpreter.name>neo4j</interpreter.name>
   </properties>
diff --git 
a/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreter.java
 
b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreter.java
index bcb9d7b..d7f8485 100644
--- 
a/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreter.java
+++ 
b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreter.java
@@ -201,6 +201,20 @@ public class Neo4jCypherInterpreter extends Interpreter {
           value = val.asList();
         } else if (val.hasType(InternalTypeSystem.TYPE_SYSTEM.MAP())) {
           value = val.asMap();
+        } else if (val.hasType(InternalTypeSystem.TYPE_SYSTEM.POINT())) {
+          value = val.asPoint();
+        } else if (val.hasType(InternalTypeSystem.TYPE_SYSTEM.DATE())) {
+          value = val.asLocalDate();
+        } else if (val.hasType(InternalTypeSystem.TYPE_SYSTEM.TIME())) {
+          value = val.asOffsetTime();
+        } else if (val.hasType(InternalTypeSystem.TYPE_SYSTEM.LOCAL_TIME())) {
+          value = val.asLocalTime();
+        } else if 
(val.hasType(InternalTypeSystem.TYPE_SYSTEM.LOCAL_DATE_TIME())) {
+          value = val.asLocalDateTime();
+        } else if (val.hasType(InternalTypeSystem.TYPE_SYSTEM.DATE_TIME())) {
+          value = val.asZonedDateTime();
+        } else if (val.hasType(InternalTypeSystem.TYPE_SYSTEM.DURATION())) {
+          value = val.asIsoDuration();
         }
       }
       if (value instanceof Collection) {
diff --git 
a/neo4j/src/test/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreterTest.java
 
b/neo4j/src/test/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreterTest.java
index 24bd513..7940d5f 100644
--- 
a/neo4j/src/test/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreterTest.java
+++ 
b/neo4j/src/test/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreterTest.java
@@ -55,10 +55,15 @@ public class Neo4jCypherInterpreterTest {
   private static final String REL_KNOWS = "KNOWS";
 
   private static final String CYPHER_FOREACH =
-          "FOREACH (x in range(1,1000) | CREATE (:%s{name: \"name\" + x, age: 
%s}))";
-  private static final String CHPHER_UNWIND = "UNWIND range(1,1000) as x "
-        + "MATCH (n), (m) WHERE id(n) = x AND id(m) = toInt(rand() * 1000) "
+          "FOREACH (x in range(1,100) | CREATE (:%s{name: \"name\" + x, age: 
%s, " +
+                  "address: point({ longitude: 56.7, latitude: 12.78, height: 
8 }), " +
+                  "birth: date('1984-04-04')}))";
+  private static final String CHPHER_UNWIND = "UNWIND range(1,100) as x "
+        + "MATCH (n), (m) WHERE id(n) = x AND id(m) = toInt(rand() * 100) "
         + "CREATE (n)-[:%s]->(m)";
+  
+  private static final String TABLE_RESULT_PREFIX = "%table ";
+  private static final String NETWORK_RESULT_PREFIX = "%network ";
 
   @BeforeClass
   public static void setUpNeo4jServer() throws Exception {
@@ -73,7 +78,7 @@ public class Neo4jCypherInterpreterTest {
   public static void tearDownNeo4jServer() throws Exception {
     server.close();
   }
-  
+
   @Before
   public void setUpZeppelin() {
     Properties p = new Properties();
@@ -83,7 +88,7 @@ public class Neo4jCypherInterpreterTest {
     interpreter = new Neo4jCypherInterpreter(p);
     context = InterpreterContext.builder()
         .setInterpreterOut(new InterpreterOutput(null))
-        .build();;
+        .build();
   }
 
   @After
@@ -98,14 +103,15 @@ public class Neo4jCypherInterpreterTest {
             "return 'a' as colA, 'b' as colB, [1, 2, 3] as colC", context);
     assertEquals(Code.SUCCESS, result.code());
     final String tableResult = "colA\tcolB\tcolC\n\"a\"\t\"b\"\t[1,2,3]\n";
-    assertEquals(tableResult, result.toString().replace("%table ", 
StringUtils.EMPTY));
-    
+    assertEquals(tableResult, result.toString().replace(TABLE_RESULT_PREFIX, 
StringUtils.EMPTY));
+
     result = interpreter.interpret(
             "return 'a' as colA, 'b' as colB, [{key: \"value\"}, {key: 1}] as 
colC", context);
     assertEquals(Code.SUCCESS, result.code());
     final String tableResultWithMap =
             
"colA\tcolB\tcolC\n\"a\"\t\"b\"\t[{\"key\":\"value\"},{\"key\":1}]\n";
-    assertEquals(tableResultWithMap, result.toString().replace("%table ", 
StringUtils.EMPTY));
+    assertEquals(tableResultWithMap, 
result.toString().replace(TABLE_RESULT_PREFIX,
+            StringUtils.EMPTY));
   }
 
   @Test
@@ -121,10 +127,14 @@ public class Neo4jCypherInterpreterTest {
     interpreter.open();
     InterpreterResult result = interpreter.interpret("MATCH (n:Person) "
             + "WHERE n.name IN ['name1', 'name2', 'name3'] "
-            + "RETURN n.name AS name, n.age AS age", context);
+            + "RETURN n.name AS name, n.age AS age, "
+            + "n.address AS address, n.birth AS birth", context);
     assertEquals(Code.SUCCESS, result.code());
-    final String tableResult = 
"name\tage\n\"name1\"\t1\n\"name2\"\t2\n\"name3\"\t3\n";
-    assertEquals(tableResult, result.toString().replace("%table ", 
StringUtils.EMPTY));
+    final String tableResult = "name\tage\taddress\tbirth\n" +
+            "\"name1\"\t1\tPoint{srid=4979, x=56.7, y=12.78, 
z=8.0}\t1984-04-04\n" +
+            "\"name2\"\t2\tPoint{srid=4979, x=56.7, y=12.78, 
z=8.0}\t1984-04-04\n" +
+            "\"name3\"\t3\tPoint{srid=4979, x=56.7, y=12.78, 
z=8.0}\t1984-04-04\n";
+    assertEquals(tableResult, result.toString().replace(TABLE_RESULT_PREFIX, 
StringUtils.EMPTY));
   }
 
   @Test
@@ -136,7 +146,7 @@ public class Neo4jCypherInterpreterTest {
     final String objectListKey = "object.listKey";
     InterpreterResult result = interpreter.interpret(jsonQuery, context);
     assertEquals(Code.SUCCESS, result.code());
-    String[] rows = result.toString().replace("%table ", StringUtils.EMPTY)
+    String[] rows = result.toString().replace(TABLE_RESULT_PREFIX, 
StringUtils.EMPTY)
             .split(Neo4jCypherInterpreter.NEW_LINE);
     assertEquals(rows.length, 2);
     List<String> header = 
Arrays.asList(rows[0].split(Neo4jCypherInterpreter.TAB));
@@ -153,7 +163,7 @@ public class Neo4jCypherInterpreterTest {
             + "AS array UNWIND array AS object RETURN object";
     result = interpreter.interpret(query, context);
     assertEquals(Code.SUCCESS, result.code());
-    rows = result.toString().replace("%table ", StringUtils.EMPTY)
+    rows = result.toString().replace(TABLE_RESULT_PREFIX, StringUtils.EMPTY)
             .split(Neo4jCypherInterpreter.NEW_LINE);
     assertEquals(rows.length, 3);
     header = Arrays.asList(rows[0].split(Neo4jCypherInterpreter.TAB));
@@ -175,7 +185,7 @@ public class Neo4jCypherInterpreterTest {
             + "AS array UNWIND array AS object RETURN object";
     result = interpreter.interpret(jsonListWithNullQuery, context);
     assertEquals(Code.SUCCESS, result.code());
-    rows = result.toString().replace("%table ", StringUtils.EMPTY)
+    rows = result.toString().replace(TABLE_RESULT_PREFIX, StringUtils.EMPTY)
             .split(Neo4jCypherInterpreter.NEW_LINE);
     assertEquals(rows.length, 3);
     header = Arrays.asList(rows[0].split(Neo4jCypherInterpreter.TAB, -1));
@@ -191,13 +201,13 @@ public class Neo4jCypherInterpreterTest {
     assertEquals(row.get(header.indexOf(objectKey)), "value2");
     assertEquals(row.get(header.indexOf(objectListKey)),
             "[{\"inner\":\"Map1\"},{\"inner\":\"Map2\"}]");
-    
+
     final String jsonListWithoutListKeyQuery = "WITH [{key: \"value\"},"
             + "{key: \"value2\", listKey: [{inner: \"Map1\"}, {inner: 
\"Map2\"}]}] "
             + "AS array UNWIND array AS object RETURN object";
     result = interpreter.interpret(jsonListWithoutListKeyQuery, context);
     assertEquals(Code.SUCCESS, result.code());
-    rows = result.toString().replace("%table ", StringUtils.EMPTY)
+    rows = result.toString().replace(TABLE_RESULT_PREFIX, StringUtils.EMPTY)
             .split(Neo4jCypherInterpreter.NEW_LINE);
     assertEquals(rows.length, 3);
     header = Arrays.asList(rows[0].split(Neo4jCypherInterpreter.TAB, -1));
@@ -219,7 +229,7 @@ public class Neo4jCypherInterpreterTest {
     interpreter.open();
     InterpreterResult result = interpreter.interpret(
             "MATCH (n)-[r:KNOWS]-(m) RETURN n, r, m LIMIT 1", context);
-    GraphResult.Graph graph = 
gson.fromJson(result.toString().replace("%network ",
+    GraphResult.Graph graph = 
gson.fromJson(result.toString().replace(NETWORK_RESULT_PREFIX,
             StringUtils.EMPTY), GraphResult.Graph.class);
     assertEquals(2, graph.getNodes().size());
     assertEquals(true, 
graph.getNodes().iterator().next().getLabel().equals(LABEL_PERSON));
@@ -248,4 +258,65 @@ public class Neo4jCypherInterpreterTest {
             context);
     assertEquals(Code.ERROR, result.code());
   }
+
+  @Test
+  public void testDates() {
+    InterpreterResult result = interpreter.interpret(
+            "RETURN datetime('2015-06-24T12:50:35.556+0100') AS theDateTime", 
context);
+    assertEquals(Code.SUCCESS, result.code());
+    assertEquals("theDateTime\n2015-06-24T12:50:35.556+01:00\n", 
result.toString()
+            .replace(TABLE_RESULT_PREFIX, StringUtils.EMPTY));
+
+    result = interpreter.interpret("RETURN localdatetime('2015185T19:32:24') 
AS theLocalDateTime",
+            context);
+    assertEquals(Code.SUCCESS, result.code());
+    assertEquals("theLocalDateTime\n2015-07-04T19:32:24\n", result.toString()
+            .replace(TABLE_RESULT_PREFIX, StringUtils.EMPTY));
+
+    result = interpreter.interpret("RETURN date('+2015-W13-4') AS theDate", 
context);
+    assertEquals(Code.SUCCESS, result.code());
+    assertEquals("theDate\n2015-03-26\n", result.toString()
+            .replace(TABLE_RESULT_PREFIX, StringUtils.EMPTY));
+
+    result = interpreter.interpret("RETURN time('125035.556+0100') AS 
theTime", context);
+    assertEquals(Code.SUCCESS, result.code());
+    assertEquals("theTime\n12:50:35.556+01:00\n", 
result.toString().replace(TABLE_RESULT_PREFIX,
+            StringUtils.EMPTY));
+
+    result = interpreter.interpret("RETURN localtime('12:50:35.556') AS 
theLocalTime", context);
+    assertEquals(Code.SUCCESS, result.code());
+    assertEquals("theLocalTime\n12:50:35.556\n", result.toString()
+            .replace(TABLE_RESULT_PREFIX, StringUtils.EMPTY));
+  }
+
+  @Test
+  public void testDuration() {
+    InterpreterResult result = interpreter.interpret(
+            "RETURN duration('P14DT16H12M') AS theDuration", context);
+    assertEquals(Code.SUCCESS, result.code());
+    assertEquals("theDuration\nP0M14DT58320S\n", result.toString()
+            .replace(TABLE_RESULT_PREFIX, StringUtils.EMPTY));
+  }
+
+  @Test
+  public void testPoint() {
+    InterpreterResult result = interpreter.interpret("RETURN point({ x:3, y:0 
}) AS cartesian_2d,"
+            + "point({ x:0, y:4, z:1 }) AS cartesian_3d,"
+            + "point({ latitude: 12, longitude: 56 }) AS geo_2d,"
+            + "point({ latitude: 12, longitude: 56, height: 1000 }) AS 
geo_3d", context);
+    assertEquals(Code.SUCCESS, result.code());
+    assertEquals("cartesian_2d\tcartesian_3d\tgeo_2d\tgeo_3d\n" +
+            "Point{srid=7203, x=3.0, y=0.0}\tPoint{srid=9157, x=0.0, y=4.0, 
z=1.0}\t" +
+            "Point{srid=4326, x=56.0, y=12.0}\tPoint{srid=4979, x=56.0, 
y=12.0, z=1000.0}\n",
+            result.toString().replace(TABLE_RESULT_PREFIX, StringUtils.EMPTY));
+
+    result = interpreter.interpret(
+            "WITH point({ latitude: 12, longitude: 56, height: 1000 }) AS 
geo_3d " +
+            "RETURN geo_3d.latitude AS latitude, geo_3d.longitude AS 
longitude, " +
+                    "geo_3d.height AS height", context);
+    assertEquals(Code.SUCCESS, result.code());
+    assertEquals("latitude\tlongitude\theight\n" +
+                    "12.0\t56.0\t1000.0\n",
+            result.toString().replace(TABLE_RESULT_PREFIX, StringUtils.EMPTY));
+  }
 }

Reply via email to